Skip to content

Commit

Permalink
Revocation development (#118)
Browse files Browse the repository at this point in the history
* Fix verification fields

* Minor changes in responce

* Fixed visibility of enums to public

* Update Core Extensions

* Added corrected localisation strings

* Fixed Warnings

* Fixed QR Code crash

* minor fix

* minor

* Added Networking to core

* Added BlumFilter functionality

* Prepared DataCenter to adding Revocations, fixed Bloom filter SHA256

* Added revocation main URL

* Added Revocation request

* Updated request factory

* Added chunk request

* Added zip loading

* UVCI and country code concat UVCI  hashes accessors

* Certificate signature hash calculation

* Marked incorrect public key for the signature algorithm check

* Added UI screens for loading

* Signature hash finalized

* Added revocation Functionality

* Imported BloomFilter

* Changed status of x and y

* Added UI

* Added minor

* Updated validity

* removed unnecessary file

Co-authored-by: IgorKhomiak <[email protected]>
Co-authored-by: Denis Melenevsky <[email protected]>
  • Loading branch information
3 people authored Feb 28, 2022
1 parent e6dfbdd commit c2081b0
Show file tree
Hide file tree
Showing 24 changed files with 1,168 additions and 341 deletions.
29 changes: 29 additions & 0 deletions Sources/Auxilary/Helper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Helper.swift
// DCCRevocation
//
// Created by Igor Khomiak on 24.01.2022.
//

import Foundation

public class Helper {

public static func convertToBase64url(base64: String) -> String {
let base64url = base64
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: "=", with: "")
return base64url
}

public static func convertToBase64(base64url: String) -> String {
var base64 = base64url
.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
if base64.count % 4 != 0 {
base64.append(String(repeating: "=", count: 4 - base64.count % 4))
}
return base64
}
}
71 changes: 71 additions & 0 deletions Sources/Auxilary/SecureKeyChain.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
/*-
* ---license-start
* eu-digital-green-certificates / dgca-wallet-app-ios
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/
//
// SecureKeyChain.swift
// DGCAWallet
//
// Created by Igor Khomiak on 18.11.2021.
//
// see https://stackoverflow.com/a/37539998/1694526


import Foundation
import Security

public class SecureKeyChain {
@discardableResult
public class func save(key: String, data: Data) -> OSStatus {
let query = [
kSecClass as String : kSecClassGenericPassword as String,
kSecAttrAccount as String : key,
kSecValueData as String : data ] as [String : Any]

SecItemDelete(query as CFDictionary)

return SecItemAdd(query as CFDictionary, nil)
}

public class func load(key: String) -> Data? {
let query = [
kSecClass as String : kSecClassGenericPassword,
kSecAttrAccount as String : key,
kSecReturnData as String : kCFBooleanTrue!,
kSecMatchLimit as String : kSecMatchLimitOne ] as [String : Any]

var dataTypeRef: AnyObject? = nil

let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)

if status == noErr {
return dataTypeRef as! Data?
} else {
return nil
}
}

public class func createUniqueID() -> String {
let uuid: CFUUID = CFUUIDCreate(nil)
let cfStr: CFString = CFUUIDCreateString(nil, uuid)

let swiftString: String = cfStr as String
return swiftString
}
}
282 changes: 282 additions & 0 deletions Sources/Auxilary/SyncArray.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
//
/*-
* ---license-start
* eu-digital-green-certificates / dgca-wallet-app-ios
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/
//
// SyncArray.swift
// DGCAWallet
//
// Created by Igor Khomiak on 19.11.2021.
//


import Foundation

/// A thread-safe array.
public class SyncArray<Element> {

fileprivate let queue = DispatchQueue(label: "Wallet.Element.SyncArray", attributes: .concurrent)
fileprivate var array = [Element]()

public init() {
}
}

// MARK: - Properties
public extension SyncArray {

var resultArray: [Element] {
return array
}

/// The first element of the collection.
var first: Element? {
var result: Element?
queue.sync { result = self.array.first }
return result
}

/// The last element of the collection.
var last: Element? {
var result: Element?
queue.sync { result = self.array.last }
return result
}

/// The number of elements in the array.
var count: Int {
var result = 0
queue.sync { result = self.array.count }
return result
}

/// A Boolean value indicating whether the collection is empty.
var isEmpty: Bool {
var result = false
queue.sync { result = self.array.isEmpty }
return result
}

/// A textual representation of the array and its elements.
var description: String {
var result = ""
queue.sync { result = self.array.description }
return result
}
}

// MARK: - Immutable
public extension SyncArray {
/// Returns the first element of the sequence that satisfies the given predicate or nil if no such element is found.
///
/// - Parameter predicate: A closure that takes an element of the sequence as its argument and returns a Boolean value indicating whether the element is a match.
/// - Returns: The first match or nil if there was no match.
func first(where predicate: (Element) -> Bool) -> Element? {
var result: Element?
queue.sync { result = self.array.first(where: predicate) }
return result
}

/// Returns an array containing, in order, the elements of the sequence that satisfy the given predicate.
/// - Returns: An array of the elements that includeElement allowed.
func filter(_ isIncluded: (Element) -> Bool) -> [Element] {
var result = [Element]()
queue.sync { result = self.array.filter(isIncluded) }
return result
}

/// Returns the first index in which an element of the collection satisfies the given predicate.
///
/// - Parameter predicate: A closure that takes an element as its argument and returns a Boolean value that indicates whether the passed element represents a match.
/// - Returns: The index of the first element for which predicate returns true. If no elements in the collection satisfy the given predicate, returns nil.
func index(where predicate: (Element) -> Bool) -> Int? {
var result: Int?
queue.sync { result = self.array.firstIndex(where: predicate) }
return result
}

/// Returns the elements of the collection, sorted using the given predicate as the comparison between elements.
///
/// - Parameter areInIncreasingOrder: A predicate that returns true if its first argument should be ordered before its second argument; otherwise, false.
/// - Returns: A sorted array of the collection’s elements.
func sorted(by areInIncreasingOrder: (Element, Element) -> Bool) -> [Element] {
var result = [Element]()
queue.sync { result = self.array.sorted(by: areInIncreasingOrder) }
return result
}

/// Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.
///
/// - Parameter transform: A closure that accepts an element of this sequence as its argument and returns an optional value.
/// - Returns: An array of the non-nil results of calling transform with each element of the sequence.
func flatMap<ElementOfResult>(_ transform: (Element) -> ElementOfResult?) -> [ElementOfResult] {
var result = [ElementOfResult]()
queue.sync { result = self.array.compactMap(transform) }
return result
}

/// Calls the given closure on each element in the sequence in the same order as a for-in loop.
///
/// - Parameter body: A closure that takes an element of the sequence as a parameter.
func forEach(_ body: (Element) -> Void) {
queue.sync { self.array.forEach(body) }
}

/// Returns a Boolean value indicating whether the sequence contains an element that satisfies the given predicate.
///
/// - Parameter predicate: A closure that takes an element of the sequence as its argument and returns a Boolean value that indicates whether the passed element represents a match.
/// - Returns: true if the sequence contains an element that satisfies predicate; otherwise, false.
func contains(where predicate: (Element) -> Bool) -> Bool {
var result = false
queue.sync { result = self.array.contains(where: predicate) }
return result
}
}

// MARK: - Mutable
public extension SyncArray {

/// Adds a new element at the end of the array.
///
/// - Parameter element: The element to append to the array.
func append( _ element: Element) {
queue.async(flags: .barrier) {
self.array.append(element)
}
}

/// Adds a new element at the end of the array.
///
/// - Parameter element: The element to append to the array.
func append( _ elements: [Element]) {
queue.async(flags: .barrier) {
self.array += elements
}
}

/// Inserts a new element at the specified position.
///
/// - Parameters:
/// - element: The new element to insert into the array.
/// - index: The position at which to insert the new element.
func insert( _ element: Element, at index: Int) {
queue.async(flags: .barrier) {
self.array.insert(element, at: index)
}
}

/// Removes and returns the element at the specified position.
///
/// - Parameters:
/// - index: The position of the element to remove.
/// - completion: The handler with the removed element.
func remove(at index: Int, completion: ((Element) -> Void)? = nil) {
queue.async(flags: .barrier) {
let element = self.array.remove(at: index)

DispatchQueue.main.async {
completion?(element)
}
}
}

/// Removes and returns the element at the specified position.
///
/// - Parameters:
/// - predicate: A closure that takes an element of the sequence as its argument and returns a Boolean value indicating whether the element is a match.
/// - completion: The handler with the removed element.
func remove(where predicate: @escaping (Element) -> Bool, completion: ((Element) -> Void)? = nil) {
queue.async(flags: .barrier) {
guard let index = self.array.firstIndex(where: predicate) else { return }
let element = self.array.remove(at: index)

DispatchQueue.main.async {
completion?(element)
}
}
}

/// Removes all elements from the array.
///
/// - Parameter completion: The handler with the removed elements.
func removeAll(completion: (([Element]) -> Void)? = nil) {
queue.async(flags: .barrier) {
let elements = self.array
self.array.removeAll()

DispatchQueue.main.async {
completion?(elements)
}
}
}
}

public extension SyncArray {

/// Accesses the element at the specified position if it exists.
///
/// - Parameter index: The position of the element to access.
/// - Returns: optional element if it exists.
subscript(index: Int) -> Element? {
get {
var result: Element?

queue.sync {
guard self.array.startIndex..<self.array.endIndex ~= index else { return }
result = self.array[index]
}

return result
}
set {
guard let newValue = newValue else { return }

queue.async(flags: .barrier) {
self.array[index] = newValue
}
}
}
}


// MARK: - Equatable
public extension SyncArray where Element: Equatable {

/// Returns a Boolean value indicating whether the sequence contains the given element.
///
/// - Parameter element: The element to find in the sequence.
/// - Returns: true if the element was found in the sequence; otherwise, false.
func contains(_ element: Element) -> Bool {
var result = false
queue.sync { result = self.array.contains(element) }
return result
}
}

// MARK: - Infix operators
public extension SyncArray {

static func +=(left: inout SyncArray, right: Element) {
left.append(right)
}

static func +=(left: inout SyncArray, right: [Element]) {
left.append(right)
}
}
Loading

0 comments on commit c2081b0

Please sign in to comment.