diff --git a/Package.resolved b/Package.resolved index 4cf41e9..40b21ed 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-model.git", "state" : { - "revision" : "bf62cc73ae2cea61e98020d2d037c153500207e7", - "version" : "0.2.5" + "revision" : "e604f0f0b67c86c3360f848defe85c9a9939b716", + "version" : "0.3.1" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { - "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5", - "version" : "1.5.4" + "revision" : "9cb486020ebf03bfa5b5df985387a14a98744537", + "version" : "1.6.1" } }, { diff --git a/Package.swift b/Package.swift index 2e2a13d..b57b40f 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), .package(url: "https://github.com/apple/swift-log.git", from: "1.5.3"), - .package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-model.git", from: "0.2.5"), + .package(url: "https://github.com/eu-digital-identity-wallet/eudi-lib-ios-iso18013-data-model.git", exact: "0.3.1"), ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. diff --git a/Sources/WalletStorage/Document.swift b/Sources/WalletStorage/Document.swift index 5c6a19f..9b85cdc 100644 --- a/Sources/WalletStorage/Document.swift +++ b/Sources/WalletStorage/Document.swift @@ -18,8 +18,8 @@ import Foundation import MdocDataModel18013 /// wallet document structure -public struct Document { - public init(id: String = UUID().uuidString, docType: String, docDataType: DocDataType, data: Data, privateKeyType: PrivateKeyType?, privateKey: Data?, createdAt: Date?, modifiedAt: Date? = nil, status: DocumentStatus) { +public struct Document: DocumentProtocol { + public init(id: String = UUID().uuidString, docType: String, docDataType: DocDataType, data: Data, privateKeyType: PrivateKeyType?, privateKey: Data?, createdAt: Date?, modifiedAt: Date? = nil, displayName: String?, status: DocumentStatus) { self.id = id self.docType = docType self.docDataType = docDataType @@ -28,6 +28,7 @@ public struct Document { self.privateKey = privateKey self.createdAt = createdAt ?? Date() self.modifiedAt = modifiedAt + self.displayName = displayName self.status = status } @@ -39,7 +40,9 @@ public struct Document { public let privateKey: Data? public let createdAt: Date public let modifiedAt: Date? + public let displayName: String? public let status: DocumentStatus + public var statusDescription: String? { status.rawValue } public var isDeferred: Bool { status == .deferred } /// get CBOR data and private key from document diff --git a/Sources/WalletStorage/Enumerations.swift b/Sources/WalletStorage/Enumerations.swift index 362a5cf..413f5e4 100644 --- a/Sources/WalletStorage/Enumerations.swift +++ b/Sources/WalletStorage/Enumerations.swift @@ -49,7 +49,8 @@ public enum PrivateKeyType: String { /// document status -public enum DocumentStatus: String { +public enum DocumentStatus: String, CaseIterable { case issued case deferred + case pending } diff --git a/Sources/WalletStorage/IssueRequest.swift b/Sources/WalletStorage/IssueRequest.swift index d9e144f..e55fb31 100644 --- a/Sources/WalletStorage/IssueRequest.swift +++ b/Sources/WalletStorage/IssueRequest.swift @@ -35,6 +35,7 @@ public struct IssueRequest { self.privateKeyType = privateKeyType if let keyData { self.keyData = keyData + // key-data already created, exit return } switch privateKeyType { @@ -51,11 +52,14 @@ public struct IssueRequest { let secureEnclaveKey = try SecureEnclave.P256.KeyAgreement.PrivateKey() self.keyData = secureEnclaveKey.dataRepresentation } + logger.info("Created private key of type \(privateKeyType)") + if let docType { logger.info(" and docType: \(docType)") } } public func saveToStorage(_ storageService: any DataStorageService, status: DocumentStatus) throws { // save key data to storage with id - let docKey = Document(id: id, docType: docType ?? "P256", docDataType: .cbor, data: Data(), privateKeyType: privateKeyType, privateKey: keyData, createdAt: Date(), status: status) + logger.info("Saving Issue request with id: \(id) and document status: \(status)") + let docKey = Document(id: id, docType: docType ?? "P256", docDataType: .cbor, data: Data(), privateKeyType: privateKeyType, privateKey: keyData, createdAt: Date(), displayName: nil, status: status) try storageService.saveDocument(docKey, allowOverwrite: true) } diff --git a/Sources/WalletStorage/KeyChainStorageService.swift b/Sources/WalletStorage/KeyChainStorageService.swift index 84e3e6f..30685f9 100644 --- a/Sources/WalletStorage/KeyChainStorageService.swift +++ b/Sources/WalletStorage/KeyChainStorageService.swift @@ -32,10 +32,12 @@ public class KeyChainStorageService: DataStorageService { /// - Parameter id: Document identifier /// - Returns: The document if exists public func loadDocument(id: String, status: DocumentStatus) throws -> Document? { - try loadDocuments(id: id, status: status)?.first + logger.info("Load document with status: \(status), id: \(id)") + return try loadDocuments(id: id, status: status)?.first } public func loadDocuments(status: DocumentStatus) throws -> [Document]? { - try loadDocuments(id: nil, status: status) + logger.info("Load documents with status: \(status)") + return try loadDocuments(id: nil, status: status) } // use is-negative to denote type of data static func isDocumentDataRow(_ d: [String: Any]) -> Bool { if let b = d[kSecAttrIsNegative as String] as? Bool { !b } else { true } } @@ -52,23 +54,20 @@ public class KeyChainStorageService: DataStorageService { return documents } - func loadDocumentsData(id: String?, docStatus: DocumentStatus, dataToLoadType: SavedKeyChainDataType = .doc, bCompatOldVersion: Bool = false) throws -> [[String: Any]]? { - var query = makeQuery(id: id, bForSave: false, status: docStatus, dataType: dataToLoadType) - if bCompatOldVersion { query[kSecAttrService as String] = if dataToLoadType == .doc { serviceName } else { serviceName + "_key" } } // to be removed in version 1 + func loadDocumentsData(id: String?, docStatus: DocumentStatus, dataToLoadType: SavedKeyChainDataType = .doc) throws -> [[String: Any]]? { + let query = makeQuery(id: id, bForSave: false, status: docStatus, dataType: dataToLoadType) var result: CFTypeRef? let status = SecItemCopyMatching(query as CFDictionary, &result) if status == errSecItemNotFound { return nil } let statusMessage = SecCopyErrorMessageString(status, nil) as? String guard status == errSecSuccess else { + logger.error("Error code: \(Int(status)), description: \(statusMessage ?? "")") throw StorageError(description: statusMessage ?? "", code: Int(status)) } var res = result as! [[String: Any]] - if !bCompatOldVersion, dataToLoadType == .doc { - if let dicts2 = try loadDocumentsData(id: id, docStatus: docStatus, dataToLoadType: .key, bCompatOldVersion: bCompatOldVersion) { res.append(contentsOf: dicts2) } + if dataToLoadType == .doc { + if let dicts2 = try loadDocumentsData(id: id, docStatus: docStatus, dataToLoadType: .key) { res.append(contentsOf: dicts2) } } - // following lines to be removed in version 1 - if !bCompatOldVersion, dataToLoadType == .doc { if let dicts1 = try loadDocumentsData(id: id, docStatus: docStatus, dataToLoadType: .doc, bCompatOldVersion: true) { res.append(contentsOf: dicts1) } } - if !bCompatOldVersion, dataToLoadType == .key { if let dicts2 = try loadDocumentsData(id: id, docStatus: docStatus, dataToLoadType: .key, bCompatOldVersion: true) {dicts2.forEach { d in var d2 = d; d2[kSecAttrIsNegative as String] = true; res.append(d2) } } } return res } @@ -107,6 +106,7 @@ public class KeyChainStorageService: DataStorageService { public func saveDocumentData(_ document: Document, dataToSaveType: SavedKeyChainDataType, dataType: String, allowOverwrite: Bool = true) throws { // kSecAttrAccount is used to store the secret Id (we save the document ID) // kSecAttrService is a key whose value is a string indicating the item's service. + logger.info("Save document for status: \(document.status), id: \(document.id), docType: \(document.docType), displayName: \(document.displayName ?? "")") guard dataType.count == 4 else { throw StorageError(description: "Invalid type") } if dataToSaveType == .key && document.privateKey == nil { throw StorageError(description: "Private key not available") } var query: [String: Any] = makeQuery(id: document.id, bForSave: true, status: document.status, dataType: dataToSaveType) @@ -117,15 +117,18 @@ public class KeyChainStorageService: DataStorageService { // use this attribute to differentiate between document and key data query[kSecAttrIsNegative as String] = Self.getIsNegativeValueToUse(dataToSaveType) query[kSecAttrLabel as String] = document.docType + if let dn = document.displayName { query[kSecAttrDescription as String] = dn } query[kSecAttrType as String] = dataType var status = SecItemAdd(query as CFDictionary, nil) if allowOverwrite && status == errSecDuplicateItem { - let updated: [String: Any] = [kSecValueData: query[kSecValueData as String] as! Data, kSecAttrIsNegative: Self.getIsNegativeValueToUse(dataToSaveType), kSecAttrLabel: document.docType, kSecAttrType: dataType] as [String: Any] + var updated: [String: Any] = [kSecValueData: query[kSecValueData as String] as! Data, kSecAttrIsNegative: Self.getIsNegativeValueToUse(dataToSaveType), kSecAttrLabel: document.docType, kSecAttrDescription: document.displayName ?? "", kSecAttrType: dataType] as [String: Any] + if let dn = document.displayName { updated[kSecAttrDescription as String] = dn } query = makeQuery(id: document.id, bForSave: true, status: document.status, dataType: dataToSaveType) status = SecItemUpdate(query as CFDictionary, updated as CFDictionary) } let statusMessage = SecCopyErrorMessageString(status, nil) as? String guard status == errSecSuccess else { + logger.error("Error code: \(Int(status)), description: \(statusMessage ?? "")") throw StorageError(description: statusMessage ?? "", code: Int(status)) } } @@ -135,6 +138,7 @@ public class KeyChainStorageService: DataStorageService { /// - Parameters: /// - id: The Id of the secret public func deleteDocument(id: String, status: DocumentStatus) throws { + logger.info("Delete document with status: \(status), id: \(id)") try deleteDocumentData(id: id, docStatus: status) } @@ -142,7 +146,13 @@ public class KeyChainStorageService: DataStorageService { let query: [String: Any] = makeQuery(id: id, bForSave: true, status: docStatus, dataType: dataType) let status = SecItemDelete(query as CFDictionary) let statusMessage = SecCopyErrorMessageString(status, nil) as? String - guard status == errSecSuccess else { throw StorageError(description: statusMessage ?? "", code: Int(status)) } + if status == errSecItemNotFound, id == nil { + let msg = statusMessage ?? "No items found" + logger.warning("\(msg)") + } else if status != errSecSuccess { + logger.error("Error code: \(Int(status)), description: \(statusMessage ?? "")") + throw StorageError(description: statusMessage ?? "", code: Int(status)) + } if dataType == .doc { try deleteDocumentData(id: id, docStatus: docStatus, dataType: .key) } } @@ -150,6 +160,7 @@ public class KeyChainStorageService: DataStorageService { /// - Parameters: /// - id: The Id of the secret public func deleteDocuments(status: DocumentStatus) throws { + logger.info("Delete documents with status: \(status)") try deleteDocumentData(id: nil, docStatus: status) } @@ -164,6 +175,6 @@ public class KeyChainStorageService: DataStorageService { keyType = PrivateKeyType(rawValue: dict2[kSecAttrType as String] as? String ?? PrivateKeyType.derEncodedP256.rawValue)! privateKeyData = (dict2[kSecValueData as String] as! Data) } - return Document(id: dict1[kSecAttrAccount as String] as! String, docType: dict1[kSecAttrLabel as String] as? String ?? "", docDataType: DocDataType(rawValue: dict1[kSecAttrType as String] as? String ?? DocDataType.cbor.rawValue) ?? DocDataType.cbor, data: data, privateKeyType: keyType, privateKey: privateKeyData, createdAt: (dict1[kSecAttrCreationDate as String] as! Date), modifiedAt: dict1[kSecAttrModificationDate as String] as? Date, status: status) + return Document(id: dict1[kSecAttrAccount as String] as! String, docType: dict1[kSecAttrLabel as String] as? String ?? "", docDataType: DocDataType(rawValue: dict1[kSecAttrType as String] as? String ?? DocDataType.cbor.rawValue) ?? DocDataType.cbor, data: data, privateKeyType: keyType, privateKey: privateKeyData, createdAt: (dict1[kSecAttrCreationDate as String] as! Date), modifiedAt: dict1[kSecAttrModificationDate as String] as? Date, displayName: dict1[kSecAttrDescription as String] as? String, status: status) } } diff --git a/Tests/WalletStorageTests/Resources/eu_pid_base64.txt b/Tests/WalletStorageTests/Resources/eu_pid_base64.txt deleted file mode 100644 index 450c67e..0000000 --- a/Tests/WalletStorageTests/Resources/eu_pid_base64.txt +++ /dev/null @@ -1 +0,0 @@ -omppc3N1ZXJBdXRohEOhASahGCFZAoUwggKBMIICJqADAgECAgkWSuWZAtwFEGQwCgYIKoZIzj0EAwIwWDELMAkGA1UEBhMCQkUxHDAaBgNVBAoTE0V1cm9wZWFuIENvbW1pc3Npb24xKzApBgNVBAMTIkVVIERpZ2l0YWwgSWRlbnRpdHkgV2FsbGV0IFRlc3QgQ0EwHhcNMjMwNTMwMTIzMDAwWhcNMjQwNTI5MTIzMDAwWjBlMQswCQYDVQQGEwJCRTEcMBoGA1UEChMTRXVyb3BlYW4gQ29tbWlzc2lvbjE4MDYGA1UEAxMvRVUgRGlnaXRhbCBJZGVudGl0eSBXYWxsZXQgVGVzdCBEb2N1bWVudCBTaWduZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR8kxP0waSqTrCz62gRpJlOWd5nmWQxwvOuCI63oQYctli9jDkSbBlZeskN-Z0HjT7zkTujS9ssvGmH0Cfpr538o4HLMIHIMB0GA1UdDgQWBBTRpLEkOTL7RXJymUjyUn2VWKdNLTAfBgNVHSMEGDAWgBQykesOHAEdFA52T2xP6kyWONr7BDAOBgNVHQ8BAf8EBAMCB4AwEgYDVR0lBAswCQYHKIGMXQUBAjAfBgNVHRIEGDAWhhRodHRwOi8vd3d3LmV1ZGl3LmRldjBBBgNVHR8EOjA4MDagNKAyhjBodHRwczovL3N0YXRpYy5ldWRpdy5kZXYvcGtpL2NybC9pc28xODAxMy1kcy5jcmwwCgYIKoZIzj0EAwIDSQAwRgIhAN5fmOce9ldSEmvyxLhP3t-B0kPKV7Fb0xiqufHr6z99AiEA_iL3MmtLV1j_Fv6G0zqNjSmIIWnaBJtaXiyAarFHCEhZBeHYGFkF3KZndmVyc2lvbmMxLjBvZGlnZXN0QWxnb3JpdGhtZ1NIQS0yNTZnZG9jVHlwZXgYZXUuZXVyb3BhLmVjLmV1ZGl3LnBpZC4xbHZhbHVlRGlnZXN0c6F4GGV1LmV1cm9wYS5lYy5ldWRpdy5waWQuMbghGCxYIFdjjZJ8R8DeBaFXRHfBo1zOB2luBNsD7e970AiwqUwTGDRYIFBZhSOZx0Bqfr2QUHE2akmGC2LZkdRRhxeis-29lu_dA1ggI_wV62n4UDkgmx7V86Iao7FQLQDscdaGQ9DUPHt_w8UYKFggKkQ8BwllRDC24SgqNXLy9ic2k4NjeqUuiKZtxmXkfbcYIFggX3zzr6v1sY43t_CEfeXdvukR_7YzE5Fa1j3Vt9z9so0YaFggFt8F0wttSTZ_XiVLu1bsV4rdViu7f2qNAO_Dcd4tDZ8YLVgg4bI5x7NU39v6Wy2IqbeHHEY11OEF9-JtKzxqrlVwppEYZ1ggq5EWtq80200WvZxk_vwiILZMhotHmKNqj43ogtu3UHkYNVgg2lkEwsCi925eEFJZjSdn4dRTUTw7RVjGQdkQKJlVgHQKWCBa2HkeKBDNzV0KWlUsweZRfJynhmY2ce5aARZ9bpRLixgiWCAlBGpvdg4XuZ7X8s_4JGp_VZ3wo3-bT8aAKp3O4RjJoRgyWCCTI2iuUqkG6QIZi-WC0xVImnU_Lfc2gIvQNveOrpInJwhYIOF_Hf4FJhDVhQYYDXqKfTLj6hD5vtR2TlfwhyZgNNPIGC9YILD8y-50rTuEF7FQQGaDw9U91yFsHOwwLBS8ADCOvL3bBVggPOlTi0kRu30wQxw7h2tyvWrB7fnOZNLaCT5-XQ9P-AAYKVggS2h6WpHn8MO-8uMBZ8Fiif1fTYlFKAYqxDkNGZ3aBx4YH1ggG05KAmTrcmm9mIYAXK1NjbVZFl3uzrpAOAgfwaF7ZJQYIVgghwbsSvM6KsJ8mWMFEazyQf5LuLpSSkSRcOHkPCEtv7MYI1ggIX1ElYJQLbSK_VPnakVUcpKbzoJpvs9ggt55fHy47HkYLlggAU63OlONKr2hS_M2SnwVeZw5t9r9cIfxJLXmXw6otm4YHlggoOSU8XFZLvMKSu_eaj1H1bHPJ5iSpfGqbY2clufEEzECWCB9ynzS2ivf4JtrZGq1XythXfVF9Hch-B9RKH12T_zXuRgkWCCSqRIRp4lZsXj3u9vuxHtyJgiracJAEmixia-9wyVzpBgwWCBrYcVnrdVnE37X4CB09K4cL5ZsaYSIpHnNgDEDue40nxgnWCCgb0JUaLvVmok2Su8UGzY6bUWTy5t8TD5t3Pr1H-V8UglYII2JKgf5FOExd2c5sBe1K9gtXGyB8irAoFmWu7QbLvetGBxYILDGAcMg8CMdvNd6QIul2MULKhEvznUXWhvdw0QYaXfwDFgg8VMf0YGnu6RgIe8DkR0vzHIaVE-2sKRkqOW5sScCP9MHWCAurJbKiBkk8GgVr-9xLTDY0RBDN3Lb2Yg3kyAzxKfJgAZYIGvQmpOLFJPm1tpheae8o72Oqenw15y1XPGvnasuS71SGCtYIA-nT-P8uWPW6h0EvvFFceTmTcGoCphju1klbcxuan24GCVYIIvrRrvd2ExiHentW6OEpLbRccigkCMnqA4W57TKfrgdGBpYIM-zM1hiC5Evo7JSYyKfH7MTcNkTYBy8sbjxL9GmcFaybWRldmljZUtleUluZm-haWRldmljZUtleaQBAiABIVggLf39aJU9Jq4MLqphgunmi7AYQVtPp7ru0oRr1I6Hi_giWCBMeIKRymNezg8YgT5z-oC7y2SLWDF6X54Iz64XwbZWNmx2YWxpZGl0eUluZm-jZnNpZ25lZMB0MjAyNC0wNS0yN1QwNzo0Mzo1NFppdmFsaWRGcm9twHQyMDI0LTA1LTI3VDA3OjQzOjU0Wmp2YWxpZFVudGlswHQyMDI1LTA1LTI3VDA3OjQzOjU0WlhA2drodlHU5uGT1ThkafaA7lo9_R-Udm3z5rIOvlV9s8pPw8AzP95wm0-cAy7zkrMq_eXBw6TdNNbl6lQ6jhm4qGpuYW1lU3BhY2VzoXgYZXUuZXVyb3BhLmVjLmV1ZGl3LnBpZC4xmCHYGFiKpGZyYW5kb21YQEPsiBa3yfWUsTAdi773X7TUpBehgrbrHbezkj99d3Uv35_ED3sdwmdDbww1dbboVfPRo7OTgeXpoZGO9ATGKHRoZGlnZXN0SUQYLGxlbGVtZW50VmFsdWVpQU5ERVJTU09OcWVsZW1lbnRJZGVudGlmaWVya2ZhbWlseV9uYW1l2BhYg6RmcmFuZG9tWEBZbBTlc61jESidWqFLploViiQRraoXoE-94g-jCDhetL2TW6WqkUBKLXp3yeVqMQBXWzIzbXIPg34aOc1POCGAaGRpZ2VzdElEGDRsZWxlbWVudFZhbHVlY0pBTnFlbGVtZW50SWRlbnRpZmllcmpnaXZlbl9uYW1l2BhYjKRmcmFuZG9tWECc_mhQwJj6B68hB-4iV1HuRPxzErjBfTNdWjH4Wb2iuHA0AVQ8zRy5Q9xhGE21hfOJqYmKMce71jL85GRgjbWWaGRpZ2VzdElEA2xlbGVtZW50VmFsdWXZA-xqMTk4NS0wMy0zMHFlbGVtZW50SWRlbnRpZmllcmpiaXJ0aF9kYXRl2BhYgaRmcmFuZG9tWECRLibZ5mHPj7fYoa4G26kyoBn4XBBXg7ZY4c4CJPYRQuDS4IJQyEHuEML1kzan0TVC-wJuAPqMGHfe_mbhBSWnaGRpZ2VzdElEGChsZWxlbWVudFZhbHVl9XFlbGVtZW50SWRlbnRpZmllcmthZ2Vfb3Zlcl8xONgYWIGkZnJhbmRvbVhA7O2gnFihNRreREmxUTdoNC_t1x6Qxv9lnyl3l4iu7men-817vI5thsq41ZaqdhdXt46jQ2YxWmPRvJWVT7f0MWhkaWdlc3RJRBggbGVsZW1lbnRWYWx1ZfVxZWxlbWVudElkZW50aWZpZXJrYWdlX292ZXJfMTXYGFiBpGZyYW5kb21YQP3YTpEHqjJtkY14oMAfWgLW636LNj1_BK8uiwhNb0wW7JZ4QtXKnYM7urHI5taqWc3YZflEGMucAlxSrgKZ2sJoZGlnZXN0SUQYaGxlbGVtZW50VmFsdWX1cWVsZW1lbnRJZGVudGlmaWVya2FnZV9vdmVyXzIx2BhYgaRmcmFuZG9tWEB77k7ZByBYBPgmH6BpZg8o3wpygBXpbtoIQkiTluSXcrBQtPjiANK-Dpdwup0gikh4CsCRykPPaz62x78OmH1caGRpZ2VzdElEGC1sZWxlbWVudFZhbHVl9HFlbGVtZW50SWRlbnRpZmllcmthZ2Vfb3Zlcl82MNgYWIGkZnJhbmRvbVhAEtirEf3zfNefVfsy64mse2AGJMr136MCH9PObz9jDDC44J3Pcn3Nb3-qgIz_PY32iaFf3cW4GrgQcTnwVWT0oGhkaWdlc3RJRBhnbGVsZW1lbnRWYWx1ZfRxZWxlbWVudElkZW50aWZpZXJrYWdlX292ZXJfNjXYGFiBpGZyYW5kb21YQI6kCtlWIXIfZh1xoCJhPQ_hTU5Cr9ySrsrwYFW36Aed8W-lT4CPCW0iuH2HrAjuUaeb4sJF10hbEyI17bIHmwNoZGlnZXN0SUQYNWxlbGVtZW50VmFsdWX0cWVsZW1lbnRJZGVudGlmaWVya2FnZV9vdmVyXzY42BhYgqRmcmFuZG9tWEB8xg_MEHmkM3fxwB4-_rbs1w8kN0R7vi1XEdDk4cTweKPC43AslD3wzJmSQ8xZhSsz7ippgJSbyzmESQIlKC-eaGRpZ2VzdElECmxlbGVtZW50VmFsdWUYJnFlbGVtZW50SWRlbnRpZmllcmxhZ2VfaW5feWVhcnPYGFiGpGZyYW5kb21YQNF00V4dz0LsG7jWEMIhqmQw0DvHyKQtNnWT4kuzmH_Uj5tdXV7ietUR3VffG8zJOkvJohY3_MiB95jtTeKmqHpoZGlnZXN0SUQYImxlbGVtZW50VmFsdWUZB8FxZWxlbWVudElkZW50aWZpZXJuYWdlX2JpcnRoX3llYXLYGFiQpGZyYW5kb21YQNz8RsUkxn3Q3b5X26SEewM3Ovg84QYyFvs4DESw1lBaoTBzCBtdfxGNgCN288V5Mbgl7gHWyDX-8_xUHAIAZ31oZGlnZXN0SUQYMmxlbGVtZW50VmFsdWVpQU5ERVJTU09OcWVsZW1lbnRJZGVudGlmaWVycWZhbWlseV9uYW1lX2JpcnRo2BhYiKRmcmFuZG9tWEC_HiUtKyG81FUTMmNbjyojCaJ4ZIfPvTCvNwdkzM-8IDpsJ3hGhXu9EfVQRho4_MvGcOsNXvcuWafN5F-YO24oaGRpZ2VzdElECGxlbGVtZW50VmFsdWVjSkFOcWVsZW1lbnRJZGVudGlmaWVycGdpdmVuX25hbWVfYmlydGjYGFiHpGZyYW5kb21YQCxicu088gije1toXDmWTM3jJOKAm9MjG4VUfpA47NMFyr4CO2tjB9EeRH8VN9DRKzTCWR3Gg5ZLJNQ_WAc5fnhoZGlnZXN0SUQYL2xlbGVtZW50VmFsdWVmU1dFREVOcWVsZW1lbnRJZGVudGlmaWVya2JpcnRoX3BsYWNl2BhYhKRmcmFuZG9tWEC--vxOEFVYj-vO9nhfoLc8sUIai2YqVXOzsJSg-GS1Bm9Pa7-sI8qio3UF9zwmBnHYbpji8PzyLB8MEYHsbx41aGRpZ2VzdElEBWxlbGVtZW50VmFsdWViU0VxZWxlbWVudElkZW50aWZpZXJtYmlydGhfY291bnRyedgYWIOkZnJhbmRvbVhAsSSTvZsjGMYe-t9LwUz1WXAZ4ONzvebOHpypwr21iuIZHzT3TfkSxrERHzvlswtB-ctHOrGI9549P_RSqohIZWhkaWdlc3RJRBgpbGVsZW1lbnRWYWx1ZWJTRXFlbGVtZW50SWRlbnRpZmllcmtiaXJ0aF9zdGF0ZdgYWIukZnJhbmRvbVhA2BmBtrGcliGfFg76lWpsBF-1lJwHBybAFPecmvkWWBwUXw_oaPIVCjlEuoQdz7-udS2bE9XLDsvVlN195gSFfmhkaWdlc3RJRBgfbGVsZW1lbnRWYWx1ZWtLQVRSSU5FSE9MTXFlbGVtZW50SWRlbnRpZmllcmpiaXJ0aF9jaXR52BhYlaRmcmFuZG9tWEBdliXuOD4tNxGqlPIgtAqJusqNJ_t_g-PDMjjrhEggMmMBRzo_pejs5zzWFC5CTDbFq-Sg_oy9cfwor6EGx_2daGRpZ2VzdElEGCFsZWxlbWVudFZhbHVlb0ZPUlRVTkFHQVRBTiAxNXFlbGVtZW50SWRlbnRpZmllcnByZXNpZGVudF9hZGRyZXNz2BhYiKRmcmFuZG9tWED3xlGOQp5RtIcBCHy9mwZM_gIjWbvV40KJe2AEe35RVXyamj3CIc-kgwsIJWEzhwdghzLcFjBThzPhOCCCM_DqaGRpZ2VzdElEGCNsZWxlbWVudFZhbHVlYlNFcWVsZW1lbnRJZGVudGlmaWVycHJlc2lkZW50X2NvdW50cnnYGFiGpGZyYW5kb21YQMTUVlkv3nfZP6Z7bCsKTh488Gt95_baPwJntpATr4mLgh73aGqXUA2g0ynmOnkQ3CGy0dH8rJF8PHYFu6KTsodoZGlnZXN0SUQYLmxlbGVtZW50VmFsdWViU0VxZWxlbWVudElkZW50aWZpZXJucmVzaWRlbnRfc3RhdGXYGFiOpGZyYW5kb21YQPsfSiqzS-k4XV9NwbD7654ihRS-wRhz8kygQtk9_-z2pie1hk1grsMJb87BgCrs25R3JayuYSZhmz_qT2O6UdJoZGlnZXN0SUQYHmxlbGVtZW50VmFsdWVrS0FUUklORUhPTE1xZWxlbWVudElkZW50aWZpZXJtcmVzaWRlbnRfY2l0edgYWI6kZnJhbmRvbVhAjKdhWuxbCPB5wqXllYj5taRxdkUyhFEJdEu91So4eAAsNrlH5lwqX5dyWDO94yujT3EgX8fnnCa938sae5S2HGhkaWdlc3RJRAJsZWxlbWVudFZhbHVlZTY0MTMzcWVsZW1lbnRJZGVudGlmaWVydHJlc2lkZW50X3Bvc3RhbF9jb2Rl2BhYkaRmcmFuZG9tWEDYGYG2sZyWIZ8WDvqVamwEX7WUnAcHJsAU95ya-RZYHBRfD-ho8hUKOUS6hB3Pv651LZsT1csOy9WU3X3mBIV-aGRpZ2VzdElEGCRsZWxlbWVudFZhbHVlbEZPUlRVTkFHQVRBTnFlbGVtZW50SWRlbnRpZmllcm9yZXNpZGVudF9zdHJlZXTYGFiNpGZyYW5kb21YQHMhZalqAAGpri5QgfBFMTTT-FHaNBvM7h__UQYYDA8-TOKJOquniZCsQ__6zJDSvdhBg7DgcLpRy6jQ21s9TxFoZGlnZXN0SUQYMGxlbGVtZW50VmFsdWViMTJxZWxlbWVudElkZW50aWZpZXJ1cmVzaWRlbnRfaG91c2VfbnVtYmVy2BhYfKRmcmFuZG9tWEDb0JVZzF4i1NZMbn9KjNPZ2AwXs3-B3IjmD-mluS_ry1aiqY_rX0eBaooPoDbIUTVFvr6i885Mb48nZGhhgwq1aGRpZ2VzdElEGCdsZWxlbWVudFZhbHVlAXFlbGVtZW50SWRlbnRpZmllcmZnZW5kZXLYGFiCpGZyYW5kb21YQIW24eR6o1hmr6_8lIAuNO0CQjyv9SI5229PUPTXQUKhSvP0utZF1du2rRQiQh9TVhzavLX6maeh6YIPV97ghYxoZGlnZXN0SUQJbGVsZW1lbnRWYWx1ZWJTRXFlbGVtZW50SWRlbnRpZmllcmtuYXRpb25hbGl0edgYWJikZnJhbmRvbVhAgnwV_iQyf2QGSE6uYOW2p3xLtWK_DK-iDHwwPFabR5StwSSma9JXqMWA3CnTe9qU72DY6rfttr7KpY0WI6w832hkaWdlc3RJRBgcbGVsZW1lbnRWYWx1ZcB0MjAwOS0wMS0wMVQwMDowMDowMFpxZWxlbWVudElkZW50aWZpZXJtaXNzdWFuY2VfZGF0ZdgYWJWkZnJhbmRvbVhAiowcyGSIgy79Dpox0vDC1esSabw7q7yZK9DCAe5gtYkDX-3oXT0ccrLteJcKjh8bNEwyFQIoA7Fn62LyhADEHmhkaWdlc3RJRAxsZWxlbWVudFZhbHVlwHQyMDUwLTAzLTMwVDAwOjAwOjAwWnFlbGVtZW50SWRlbnRpZmllcmtleHBpcnlfZGF0ZdgYWImkZnJhbmRvbVhAcy6WLDiYVc1UTzpKGr73R85Z47uO4lbFzuHwS2tHczP9Nzu-RLgMjGT7QbKHPRwwnDnE19qSjKvl7PVkYz6YBWhkaWdlc3RJRAdsZWxlbWVudFZhbHVlY1VUT3FlbGVtZW50SWRlbnRpZmllcnFpc3N1aW5nX2F1dGhvcml0edgYWI2kZnJhbmRvbVhA_yBHjAHmxXcD5F5E7uH61Fuvu3rRAMsFM3XnGev0qiY2E68ptPF5Pif_t74UHsQgB71QdMXlj6qq_VGieVCUoGhkaWdlc3RJRAZsZWxlbWVudFZhbHVlaTExMTExMTExNHFlbGVtZW50SWRlbnRpZmllcm9kb2N1bWVudF9udW1iZXLYGFiVpGZyYW5kb21YQGR1Hvlm41HdMvqz86rz0-tuMaUaGm_kyjFvT5p60knz--dv-htZC8pUugoHahEzLIaa29FajEDpxtZBXXJ7jvNoZGlnZXN0SUQYK2xlbGVtZW50VmFsdWVqOTAxMDE2NzQ2NHFlbGVtZW50SWRlbnRpZmllcnVhZG1pbmlzdHJhdGl2ZV9udW1iZXLYGFiHpGZyYW5kb21YQMjoQx3iRtzw7AJKwu-BIdtm01ivNfqejekxh9oBJ5GwXAwHJVfB9IpYoLt_Jg36hMwxwKnObQXc6Gsiq0CFvaloZGlnZXN0SUQYJWxlbGVtZW50VmFsdWViU0VxZWxlbWVudElkZW50aWZpZXJvaXNzdWluZ19jb3VudHJ52BhYjqRmcmFuZG9tWEB6pSEMLXaDJFLYp7zIqS2uWV-MiN9atCpSDe5nsvhb1gNZOa12EWihlFJEr57u0hqAy5pgSuE4FLR-ExI_WF3laGRpZ2VzdElEGBpsZWxlbWVudFZhbHVlZFNFLUlxZWxlbWVudElkZW50aWZpZXJ0aXNzdWluZ19qdXJpc2RpY3Rpb24 diff --git a/Tests/WalletStorageTests/WalletStorageTests.swift b/Tests/WalletStorageTests/WalletStorageTests.swift index 8dc7517..2d259c1 100644 --- a/Tests/WalletStorageTests/WalletStorageTests.swift +++ b/Tests/WalletStorageTests/WalletStorageTests.swift @@ -12,13 +12,7 @@ final class WalletStorageTests: XCTestCase { XCTAssert(Bool(pem.count > 0)) print(pem) } - - func testLoadPidIssuerSigned() { - let base64str = String(data: Data(name: "eu_pid_base64", ext: "txt", from: Bundle.module)!, encoding: .utf8)! - let pidIssueredSignedData = [UInt8](Data(base64URLEncoded: base64str.trimmingCharacters(in: .whitespacesAndNewlines))!) - let pidIssueredSigned = IssuerSigned(data: pidIssueredSignedData) - XCTAssertEqual(EuPidModel.euPidDocType, pidIssueredSigned?.issuerNameSpaces?.nameSpaces.map(\.key).first, "Test data contains PID doc type") - } + } diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..f478d8b --- /dev/null +++ b/changelog.md @@ -0,0 +1,11 @@ +- Refactor to support Deferred document issuing ([#15](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/issues/15)) via [@phisakel](https://github.com/phisakel) +- Document getCborData() must return IssuerSigned data ([#12](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/issues/12)) via [@phisakel](https://github.com/phisakel) +- Add unit test for cbor data, Document getCborData() returns IssuerSigned ([#11](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/11)) via [@phisakel](https://github.com/phisakel) +- Feature/central sec workflows ([#8](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/8)) via [@christosservosNCIN](https://github.com/christosservosNCIN) +- Update README.md ([#10](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/10)) via [@vkanellopoulos](https://github.com/vkanellopoulos) +- Update SECURITY.md ([#9](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/9)) via [@vkanellopoulos](https://github.com/vkanellopoulos) +- Refactor Issue request objct ([#7](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/7)) via [@phisakel](https://github.com/phisakel) +- Develop ([#6](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/6)) via [@phisakel](https://github.com/phisakel) +- Update README and SECURITY.md files ([#5](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/5)) via [@phisakel](https://github.com/phisakel) +- Develop ([#4](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/4)) via [@phisakel](https://github.com/phisakel) +- Develop ([#3](https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage/pull/3)) via [@phisakel](https://github.com/phisakel) \ No newline at end of file