From 89813bafed0490d1dab17e1c2c243e41bebcd455 Mon Sep 17 00:00:00 2001 From: Andy Qua Date: Wed, 3 Jul 2024 15:05:03 +0100 Subject: [PATCH] Updated to OpenSSL 1.1.2300 (signed and privacy framework support) Reverted previous code change to turn on extended mode support for AA as some passports don't support this Instead, we habe a flag for extended mode support (new parameter on PassportReader defaults to false) Sample app removes spaces from OCRd MRZ String - improves recognition vastly --- .../MrzScanner/VisionViewController.swift | 3 +++ .../NFCPassportReaderApp/Views/MainView.swift | 2 +- Package.swift | 2 +- Sources/NFCPassportReader/PassportReader.swift | 6 ++++-- Sources/NFCPassportReader/SecureMessaging.swift | 8 ++++---- Sources/NFCPassportReader/TagReader.swift | 15 ++++++++++----- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift b/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift index fa2489cd..d2a10f2d 100644 --- a/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift +++ b/Examples/Example_SPM/NFCPassportReaderApp/MrzScanner/VisionViewController.swift @@ -68,6 +68,9 @@ public class VisionViewController: ViewController { guard let candidate = visionResult.topCandidates(maximumCandidates).first else { continue } var numberIsSubstring = true + + // Remove spaces from candidate.string - improves recognition vastly + let mrz = candidate.string.replacingOccurrences(of: " ", with: "") if let result = candidate.string.checkMrz() { if(result != "nil"){ diff --git a/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift b/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift index 5f2ed72e..247967c0 100644 --- a/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift +++ b/Examples/Example_SPM/NFCPassportReaderApp/Views/MainView.swift @@ -206,7 +206,7 @@ extension MainView { } do { - let passport = try await passportReader.readPassport( mrzKey: mrzKey, customDisplayMessage:customMessageHandler) + let passport = try await passportReader.readPassport( mrzKey: mrzKey, useExtendedMode: false, customDisplayMessage:customMessageHandler) if let _ = passport.faceImageInfo { print( "Got face Image details") diff --git a/Package.swift b/Package.swift index 72fffade..d0333dd5 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/krzyzanowskim/OpenSSL.git", .upToNextMinor(from: "1.1.1900")) + .package(url: "https://github.com/krzyzanowskim/OpenSSL.git", .upToNextMinor(from: "1.1.2300")) ], targets: [ diff --git a/Sources/NFCPassportReader/PassportReader.swift b/Sources/NFCPassportReader/PassportReader.swift index ecfd47ae..773f469b 100644 --- a/Sources/NFCPassportReader/PassportReader.swift +++ b/Sources/NFCPassportReader/PassportReader.swift @@ -28,6 +28,7 @@ public class PassportReader : NSObject { private var skipSecureElements = true private var skipCA = false private var skipPACE = false + private var useExtendedMode = false private var bacHandler : BACHandler? private var caHandler : ChipAuthenticationHandler? @@ -62,12 +63,13 @@ public class PassportReader : NSObject { dataAmountToReadOverride = amount } - public func readPassport( mrzKey : String, tags : [DataGroupId] = [], skipSecureElements : Bool = true, skipCA : Bool = false, skipPACE : Bool = false, customDisplayMessage : ((NFCViewDisplayMessage) -> String?)? = nil) async throws -> NFCPassportModel { + public func readPassport( mrzKey : String, tags : [DataGroupId] = [], skipSecureElements : Bool = true, skipCA : Bool = false, skipPACE : Bool = false, useExtendedMode : Bool = false, customDisplayMessage : ((NFCViewDisplayMessage) -> String?)? = nil) async throws -> NFCPassportModel { self.passport = NFCPassportModel() self.mrzKey = mrzKey self.skipCA = skipCA self.skipPACE = skipPACE + self.useExtendedMode = useExtendedMode self.dataGroupsToRead.removeAll() self.dataGroupsToRead.append( contentsOf:tags) @@ -267,7 +269,7 @@ extension PassportReader { let challenge = generateRandomUInt8Array(8) Logger.passportReader.debug( "Generated Active Authentication challange - \(binToHexRep(challenge))") - let response = try await tagReader.doInternalAuthentication(challenge: challenge) + let response = try await tagReader.doInternalAuthentication(challenge: challenge, useExtendedMode: useExtendedMode) self.passport.verifyActiveAuthentication( challenge:challenge, signature:response.data ) } diff --git a/Sources/NFCPassportReader/SecureMessaging.swift b/Sources/NFCPassportReader/SecureMessaging.swift index c1f21f56..5d3ec7b0 100644 --- a/Sources/NFCPassportReader/SecureMessaging.swift +++ b/Sources/NFCPassportReader/SecureMessaging.swift @@ -30,7 +30,7 @@ public class SecureMessaging { private var ssc : [UInt8] private let algoName : SecureMessagingSupportedAlgorithms private let padLength : Int - + public init( encryptionAlgorithm : SecureMessagingSupportedAlgorithms = .DES, ksenc : [UInt8], ksmac : [UInt8], ssc : [UInt8]) { self.ksenc = ksenc self.ksmac = ksmac @@ -40,7 +40,7 @@ public class SecureMessaging { } /// Protect the apdu following the doc9303 specification - func protect(apdu : NFCISO7816APDU ) throws -> NFCISO7816APDU { + func protect(apdu : NFCISO7816APDU, useExtendedMode: Bool = false ) throws -> NFCISO7816APDU { Logger.secureMessaging.debug("\t\tSSC: \(binToHexRep(self.ssc))") self.ssc = self.incSSC() @@ -88,7 +88,7 @@ public class SecureMessaging { // otherwise its a single byte of size let size = do87.count + do97.count + do8e.count var dataSize: [UInt8] - if size > 255 || apdu.expectedResponseLength > 231 { + if size > 255 || (useExtendedMode && apdu.expectedResponseLength > 231) { dataSize = [0x00] + intToBin(size, pad: 4) } else { dataSize = intToBin(size) @@ -98,7 +98,7 @@ public class SecureMessaging { // If the data is more that 255, specify the we are using extended length (0x00, 0x00) // Thanks to @filom for the fix! - if size > 255 || apdu.expectedResponseLength > 231 { + if size > 255 || (useExtendedMode && apdu.expectedResponseLength > 231) { protectedAPDU += [0x00,0x00] } else { protectedAPDU += [0x00] diff --git a/Sources/NFCPassportReader/TagReader.swift b/Sources/NFCPassportReader/TagReader.swift index 2212a416..5a9e6609 100644 --- a/Sources/NFCPassportReader/TagReader.swift +++ b/Sources/NFCPassportReader/TagReader.swift @@ -49,12 +49,17 @@ public class TagReader { return try await send( cmd: cmd ) } - func doInternalAuthentication( challenge: [UInt8] ) async throws -> ResponseAPDU { + func doInternalAuthentication( challenge: [UInt8], useExtendedMode: Bool ) async throws -> ResponseAPDU { let randNonce = Data(challenge) - let cmd = NFCISO7816APDU(instructionClass: 00, instructionCode: 0x88, p1Parameter: 0, p2Parameter: 0, data: randNonce, expectedResponseLength: 65536) + var responseLength = 256 + if useExtendedMode { + responseLength = 65535 + } + + let cmd = NFCISO7816APDU(instructionClass: 00, instructionCode: 0x88, p1Parameter: 0, p2Parameter: 0, data: randNonce, expectedResponseLength: responseLength) - return try await send( cmd: cmd ) + return try await send( cmd: cmd, useExtendedMode: useExtendedMode ) } func doMutualAuthentication( cmdData : Data ) async throws -> ResponseAPDU{ @@ -249,11 +254,11 @@ public class TagReader { return try await send( cmd: cmd ) } - func send( cmd: NFCISO7816APDU ) async throws -> ResponseAPDU { + func send( cmd: NFCISO7816APDU, useExtendedMode : Bool = false ) async throws -> ResponseAPDU { Logger.tagReader.debug( "TagReader - sending \(cmd)" ) var toSend = cmd if let sm = secureMessaging { - toSend = try sm.protect(apdu:cmd) + toSend = try sm.protect(apdu:cmd, useExtendedMode: useExtendedMode) Logger.tagReader.debug("TagReader - [SM] \(toSend)" ) }