Skip to content

Commit

Permalink
Merge pull request #479 from metsma/nfc
Browse files Browse the repository at this point in the history
NFC Support
  • Loading branch information
Counter178 authored Apr 28, 2024
2 parents 8a5f2dc + 7b08ae5 commit df1cc08
Show file tree
Hide file tree
Showing 20 changed files with 1,246 additions and 66 deletions.
28 changes: 26 additions & 2 deletions MoppApp/MoppApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
4E59080024B0F914001B23A6 /* SmartIDEditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E5907FF24B0F914001B23A6 /* SmartIDEditViewController.swift */; };
4E59080224B258C7001B23A6 /* SmartIDChallengeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59080124B258C6001B23A6 /* SmartIDChallengeViewController.swift */; };
4E59080424B2E295001B23A6 /* SmartIDSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59080324B2E295001B23A6 /* SmartIDSignature.swift */; };
4E6E1D9B2AAB493A008B3E74 /* NFCEditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6E1D9A2AAB493A008B3E74 /* NFCEditViewController.swift */; };
4EE56D232AB0561C002648EE /* NFCSignature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE56D222AB0561C002648EE /* NFCSignature.swift */; };
4EE56D272AB058A6002648EE /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = 4EE56D262AB058A6002648EE /* SwiftECC */; };
540786E91E1A76640016ABA7 /* UITextView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 540786E81E1A76640016ABA7 /* UITextView+Additions.swift */; };
547BDF251E8BEFA30093931F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E4250D0D1E0AA8E500530370 /* Localizable.strings */; };
54825EF51E1CFE9600253FF0 /* Date+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54825EF41E1CFE9600253FF0 /* Date+Additions.swift */; };
Expand Down Expand Up @@ -370,6 +373,8 @@
4E5907FF24B0F914001B23A6 /* SmartIDEditViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartIDEditViewController.swift; sourceTree = "<group>"; };
4E59080124B258C6001B23A6 /* SmartIDChallengeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartIDChallengeViewController.swift; sourceTree = "<group>"; };
4E59080324B2E295001B23A6 /* SmartIDSignature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartIDSignature.swift; sourceTree = "<group>"; };
4E6E1D9A2AAB493A008B3E74 /* NFCEditViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NFCEditViewController.swift; sourceTree = "<group>"; };
4EE56D222AB0561C002648EE /* NFCSignature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NFCSignature.swift; sourceTree = "<group>"; };
540786E81E1A76640016ABA7 /* UITextView+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextView+Additions.swift"; sourceTree = "<group>"; };
54825EF41E1CFE9600253FF0 /* Date+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Additions.swift"; sourceTree = "<group>"; };
54825EF71E1D270F00253FF0 /* String+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Additions.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -644,6 +649,7 @@
393B66E820DB9C19001DC89B /* CryptoLib.framework in Frameworks */,
DF135630290201A100F61823 /* ExternalAccessory.framework in Frameworks */,
DF1503AB2AC5D1E5007222B2 /* ZIPFoundation in Frameworks */,
4EE56D272AB058A6002648EE /* SwiftECC in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -677,6 +683,7 @@
C54EA6E72045A9E30039AC78 /* IdCardViewController.swift */,
C54BB10E1FBD93A100A274F6 /* MobileIDChallengeViewController.swift */,
C537AE532004C29E009037E5 /* MobileIDEditViewController.swift */,
4E6E1D9A2AAB493A008B3E74 /* NFCEditViewController.swift */,
4E59080124B258C6001B23A6 /* SmartIDChallengeViewController.swift */,
4E5907FF24B0F914001B23A6 /* SmartIDEditViewController.swift */,
C50DCD1A1FD1576B00D48E16 /* SigningTableViewHeaderView.swift */,
Expand Down Expand Up @@ -734,8 +741,7 @@
children = (
C50DCCD01FC573FB00D48E16 /* Roboto */,
);
name = Fonts;
path = "New Group";
path = Fonts;
sourceTree = "<group>";
};
C50DCCD01FC573FB00D48E16 /* Roboto */ = {
Expand Down Expand Up @@ -1202,6 +1208,7 @@
DFDF02C3241ED0CA006CF443 /* MobileIDSignature.swift */,
4E59080324B2E295001B23A6 /* SmartIDSignature.swift */,
DFBDF20127DF7ED700A5CF3C /* IDCardSignature.swift */,
4EE56D222AB0561C002648EE /* NFCSignature.swift */,
DFDF02BD241EB5D3006CF443 /* SessionCertificate.swift */,
E4C53F4D1E30D13100F209BE /* Session.swift */,
DFDF02BF241EC72C006CF443 /* SessionStatus.swift */,
Expand Down Expand Up @@ -1296,6 +1303,7 @@
DF1503A52AC5D1B9007222B2 /* FirebaseCrashlytics */,
DF1503A72AC5D1DB007222B2 /* SwiftyRSA */,
DF1503AA2AC5D1E5007222B2 /* ZIPFoundation */,
4EE56D262AB058A6002648EE /* SwiftECC */,
);
productName = MoppApp;
productReference = E4250CC31E0968D200530370 /* MoppApp.app */;
Expand Down Expand Up @@ -1348,6 +1356,7 @@
DF15037C2AC5CD32007222B2 /* XCRemoteSwiftPackageReference "SwiftyRSA" */,
DF15037F2AC5CD8D007222B2 /* XCRemoteSwiftPackageReference "ZIPFoundation" */,
DF1503822AC5CDBC007222B2 /* XCRemoteSwiftPackageReference "ASN1Decoder" */,
4EE56D252AB058A6002648EE /* XCRemoteSwiftPackageReference "SwiftECC" */,
);
productRefGroup = E4250CC41E0968D200530370 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -1607,6 +1616,7 @@
C50DCD461FDECE2B00D48E16 /* SignatureDetailsViewController.swift in Sources */,
DF5BE6D429C8BD5600331609 /* WarningDetail.swift in Sources */,
DF32A6812909F0FA00AE5F82 /* FileLogUtil.swift in Sources */,
4EE56D232AB0561C002648EE /* NFCSignature.swift in Sources */,
C50DCCFF1FC6E95A00D48E16 /* ContainerViewController.swift in Sources */,
C50DCD481FDED76400D48E16 /* SignatureDetailsCell.swift in Sources */,
DF0C2B3F29150EAB007E1745 /* ScaledLabel.swift in Sources */,
Expand Down Expand Up @@ -1680,6 +1690,7 @@
C506EC811FB9F4AF00E07226 /* UIImage+Additions.swift in Sources */,
C55A6E42208766BA000F3386 /* MyeIDChangeCodesLoadingViewController.swift in Sources */,
DFDC0ABA29FAD8F2002D1D1D /* ViewUtil.swift in Sources */,
4E6E1D9B2AAB493A008B3E74 /* NFCEditViewController.swift in Sources */,
DFD8BEF5291C432400FE8F07 /* ScaledButton.swift in Sources */,
C5927FC720751402003B7F41 /* MyeIDPinPukCell.swift in Sources */,
DFF3C3AF233231190079458A /* SettingsConfiguration.swift in Sources */,
Expand Down Expand Up @@ -2125,6 +2136,14 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
4EE56D252AB058A6002648EE /* XCRemoteSwiftPackageReference "SwiftECC" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/leif-ibsen/SwiftECC";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 4.0.0;
};
};
DF1503792AC5CCE7007222B2 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git";
Expand Down Expand Up @@ -2160,6 +2179,11 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
4EE56D262AB058A6002648EE /* SwiftECC */ = {
isa = XCSwiftPackageProductDependency;
package = 4EE56D252AB058A6002648EE /* XCRemoteSwiftPackageReference "SwiftECC" */;
productName = SwiftECC;
};
DF1503A32AC5D163007222B2 /* ASN1Decoder */ = {
isa = XCSwiftPackageProductDependency;
package = DF1503822AC5CDBC007222B2 /* XCRemoteSwiftPackageReference "ASN1Decoder" */;
Expand Down
4 changes: 4 additions & 0 deletions MoppApp/MoppApp/AlertUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class AlertUtil {
case .cancelled:
topViewController.dismiss(animated: true)
return
case .nfcCancelled:
return
default:
break
}
Expand All @@ -71,6 +73,8 @@ class AlertUtil {
case .cancelled:
topViewController.dismiss(animated: true)
return
case .nfcCancelled:
return
default:
break
}
Expand Down
2 changes: 1 addition & 1 deletion MoppApp/MoppApp/CancelUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ class CancelUtil {

static func handleCancelledRequest(errorMessageDetails: String) {
CancelRequestUtil.handleRequestCancellation()
ErrorUtil.generateError(signingError: .cancelled, details: MessageUtil.errorMessageWithDetails(details: errorMessageDetails))
ErrorUtil.generateError(signingError: .nfcCancelled, details: MessageUtil.errorMessageWithDetails(details: errorMessageDetails))
}
}
6 changes: 6 additions & 0 deletions MoppApp/MoppApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NFCReaderUsageDescription</key>
<string>This app uses NFC to scan ID-cards</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
Expand Down Expand Up @@ -1020,5 +1022,9 @@
</dict>
</dict>
</array>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A000000077010800070000FE000001</string>
</array>
</dict>
</plist>
48 changes: 24 additions & 24 deletions MoppApp/MoppApp/KeychainUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,52 @@ class KeychainUtil {
static func save(key: String, info: String) -> Bool {
guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return false }
if let data = info.data(using: .utf8) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: bundleIdentifier,
kSecAttrAccount as String: "\(bundleIdentifier).\(key)",
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let query: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: bundleIdentifier,
kSecAttrAccount: "\(bundleIdentifier).\(key)",
kSecValueData: data,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)

return status == errSecSuccess
}
return false
}

static func retrieve(key: String) -> String? {
guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return nil }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: bundleIdentifier,
kSecAttrAccount as String: "\(bundleIdentifier).\(key)",
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let query: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: bundleIdentifier,
kSecAttrAccount: "\(bundleIdentifier).\(key)",
kSecReturnData: true,
kSecMatchLimit: kSecMatchLimitOne,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]

var infoData: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &infoData)

if status == errSecSuccess, let data = infoData as? Data {
return String(data: data, encoding: .utf8)
} else {
return nil
}
}

static func remove(key: String) {
guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return }
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: bundleIdentifier,
kSecAttrAccount as String: "\(bundleIdentifier).\(key)"
let query: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: bundleIdentifier,
kSecAttrAccount: "\(bundleIdentifier).\(key)"
]

let status = SecItemDelete(query as CFDictionary)

if status != errSecSuccess {
printLog("Error removing key from Keychain: \(status)")
}
Expand Down
16 changes: 16 additions & 0 deletions MoppApp/MoppApp/LocalizationKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,21 @@ enum LocKey : String
case smartIdCountryLithuania = "smart-id-country-lithuania"
case smartIdCountryLatvia = "smart-id-country-latvia"
case smartIdChallengeTitle = "smart-id-challenge-title"
case nfcTitle = "nfc-title"
case nfcCANTitle = "nfc-can-title"
case nfcDeviceNoSupport = "nfc-device-no-support"
case nfcHoldNear = "nfc-hold-near"
case nfcMultipleCards = "nfc-multiple-cards"
case nfcInvalidTag = "nfc-invalid-tag"
case nfcUnableConnect = "nfc-unable-connect"
case nfcAuth = "nfc-auth"
case nfcReadingCert = "nfc-reading-cert"
case nfcSignDoc = "nfc-sign-doc"
case nfcSignDone = "nfc-sign-done"
case nfcAuthFailed = "nfc-auth-failed"
case nfcSignFailed = "nfc-sign-failed"
case nfcPinInvalid = "nfc-pin-invalid"
case nfcPinLocked = "nfc-pin-locked"
case containerSignTitle = "container-sign-title"
case containerEncryptionTitle = "container-encryption-title"
case containerDecryptionTitle = "container-decryption-title"
Expand All @@ -190,6 +205,7 @@ enum LocKey : String
case signTitleMobileId = "sign-title-mobile-id"
case signTitleSmartId = "sign-title-smart-id"
case signTitleIdCard = "sign-title-id-card"
case signTitleNFC = "sign-title-nfc"
case cardReaderStateReaderNotFound = "card-reader-state-reader-not-found"
case cardReaderStateReaderRestarted = "card-reader-state-reader-restarted"
case cardReaderStateReaderProcessFailed = "card-reader-state-reader-process-failed"
Expand Down
4 changes: 4 additions & 0 deletions MoppApp/MoppApp/MoppApp.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.ee.ria.digidoc.ios</string>
Expand Down
20 changes: 10 additions & 10 deletions MoppApp/MoppApp/MyEid.storyboard
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="qFP-og-5IC">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="qFP-og-5IC">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
Expand Down Expand Up @@ -72,11 +72,11 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Qrp-ZX-mtd">
<rect key="frame" x="16" y="25" width="343" height="617"/>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalCentering" spacing="48" translatesAutoresizingMaskIntoConstraints="NO" id="Qrp-ZX-mtd">
<rect key="frame" x="25" y="333.5" width="325" height="0.0"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pwG-59-c68" customClass="ScaledLabel" customModule="MoppApp" customModuleProvider="target">
<rect key="frame" x="171.5" y="0.0" width="0.0" height="617"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pwG-59-c68" customClass="ScaledLabel" customModule="MoppApp" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="325" height="0.0"/>
<fontDescription key="fontDescription" name="Roboto-Medium" family="Roboto" pointSize="20"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
Expand All @@ -87,10 +87,10 @@
<viewLayoutGuide key="safeArea" id="DqR-NQ-ADW"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="Qrp-ZX-mtd" secondAttribute="trailing" constant="16" id="ASj-5k-e8A"/>
<constraint firstItem="Qrp-ZX-mtd" firstAttribute="leading" secondItem="9cX-nZ-t1m" secondAttribute="leading" constant="16" id="Elo-cB-Fxt"/>
<constraint firstItem="Qrp-ZX-mtd" firstAttribute="top" secondItem="9cX-nZ-t1m" secondAttribute="top" constant="25" id="L9Y-2q-lHw"/>
<constraint firstAttribute="bottom" secondItem="Qrp-ZX-mtd" secondAttribute="bottom" constant="25" id="MXc-vA-zNR"/>
<constraint firstItem="Qrp-ZX-mtd" firstAttribute="leading" secondItem="DqR-NQ-ADW" secondAttribute="leading" constant="25" id="EDS-lq-bcD"/>
<constraint firstItem="Qrp-ZX-mtd" firstAttribute="centerY" secondItem="9cX-nZ-t1m" secondAttribute="centerY" id="GvK-nZ-7kU"/>
<constraint firstItem="Qrp-ZX-mtd" firstAttribute="centerX" secondItem="9cX-nZ-t1m" secondAttribute="centerX" id="KPP-yW-apv"/>
<constraint firstItem="DqR-NQ-ADW" firstAttribute="trailing" secondItem="Qrp-ZX-mtd" secondAttribute="trailing" constant="25" id="Net-6N-O97"/>
</constraints>
</view>
<connections>
Expand Down
3 changes: 0 additions & 3 deletions MoppApp/MoppApp/MyeIDStatusViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ class MyeIDStatusViewController : MoppViewController {
spinnerView.show(true)
spinnerView.translatesAutoresizingMaskIntoConstraints = false
statusStackView.addArrangedSubview(spinnerView)
NSLayoutConstraint.activate([
spinnerView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16)
])
loadingView = spinnerView
}
}
Expand Down
Loading

0 comments on commit df1cc08

Please sign in to comment.