Skip to content
This repository has been archived by the owner on Oct 19, 2022. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank Gregor committed Jun 4, 2020
1 parent 0da1451 commit 9cbc4b7
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 45 deletions.
8 changes: 0 additions & 8 deletions ios/OX Coi/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,6 @@ class AppDelegate: FlutterAppDelegate {
Messaging.messaging().apnsToken = deviceToken
}

override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
NSLog("[AppDelegate] didReceive response")
}

override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
NSLog("[AppDelegate] didReceiveRemoteNotification")
}

override func applicationDidEnterBackground(_ application: UIApplication) {
NSLog("[AppDelegate] applicationDidEnterBackground")
if UserDefaults.applicationShouldTerminate {
Expand Down
39 changes: 16 additions & 23 deletions ios/OX Coi/Extensions/UIKit/AppDelegate+Security.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import UIKit

extension AppDelegate {

internal func setupSecurityMethodChannel() {
guard let controller = window.rootViewController as? FlutterViewController else {
return
Expand All @@ -53,33 +53,26 @@ extension AppDelegate {
channel.setMethodCallHandler {(call: FlutterMethodCall, result: FlutterResult) -> Void in
switch call.method {
case MethodChannel.Security.Method.Decrypt:
guard let arguments = call.arguments as? [String: String],
let encryptedBase64Content = arguments[MethodChannel.Security.Argument.Content],
let privateKeyBase64 = arguments[MethodChannel.Security.Argument.PrivateKey],
let publicKeyBase64 = arguments[MethodChannel.Security.Argument.PublicKey],
let authBase64 = arguments[MethodChannel.Security.Argument.Auth] else {

//TODO: Implement a valid plausible exception!
result(nil)
return
if let messageDict = call.arguments as? [String: String] {
let securityHelper = SecurityHelper(message: messageDict)
result(securityHelper.decryptedMessage)
return
}

log.debug("Arguments: \(arguments)")
/*
String encryptedBase64Content = call.argument(MethodChannels.Security.Arguments.CONTENT);
String privateKeyBase64 = call.argument(MethodChannels.Security.Arguments.PRIVATE_KEY);
String publicKeyBase64 = call.argument(MethodChannels.Security.Arguments.PUBLIC_KEY);
String authBase64 = call.argument(MethodChannels.Security.Arguments.AUTH);
byte[] inputBytes = Base64.decode(encryptedBase64Content, Base64.DEFAULT);
String decryptMessage = securityHelper.decryptMessage(inputBytes, privateKeyBase64, publicKeyBase64, authBase64);
result.success(decryptMessage);
*/
default:
break
break
}

result(nil)
}
}

}

/*
String encryptedBase64Content = call.argument(MethodChannels.Security.Arguments.CONTENT);
String privateKeyBase64 = call.argument(MethodChannels.Security.Arguments.PRIVATE_KEY);
String publicKeyBase64 = call.argument(MethodChannels.Security.Arguments.PUBLIC_KEY);
String authBase64 = call.argument(MethodChannels.Security.Arguments.AUTH);
byte[] inputBytes = Base64.decode(encryptedBase64Content, Base64.DEFAULT);
String decryptMessage = securityHelper.decryptMessage(inputBytes, privateKeyBase64, publicKeyBase64, authBase64);
result.success(decryptMessage);
*/
151 changes: 151 additions & 0 deletions ios/OX Coi/Helper/SecurityHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* OPEN-XCHANGE legal information
*
* All intellectual property rights in the Software are protected by
* international copyright laws.
*
*
* In some countries OX, OX Open-Xchange and open xchange
* as well as the corresponding Logos OX Open-Xchange and OX are registered
* trademarks of the OX Software GmbH group of companies.
* The use of the Logos is not covered by the Mozilla Public License 2.0 (MPL 2.0).
* Instead, you are allowed to use these Logos according to the terms and
* conditions of the Creative Commons License, Version 2.5, Attribution,
* Non-commercial, ShareAlike, and the interpretation of the term
* Non-commercial applicable to the aforementioned license is published
* on the web site https://www.open-xchange.com/terms-and-conditions/.
*
* Please make sure that third-party modules and libraries are used
* according to their respective licenses.
*
* Any modifications to this package must retain all copyright notices
* of the original copyright holder(s) for the original code used.
*
* After any such modifications, the original and derivative code shall remain
* under the copyright of the copyright holder(s) and/or original author(s) as stated here:
* https://www.open-xchange.com/legal/. The contributing author shall be
* given Attribution for the derivative code and a license granting use.
*
* Copyright (C) 2016-2020 OX Software GmbH
* Mail: [email protected]
*
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public License 2.0
* for more details.
*/

import Foundation
import Tink
import CryptoKit
import GMEllipticCurveCrypto

class SecurityHelper {

typealias PrivateKeyType = (privateKey: P256.KeyAgreement.PrivateKey, privateKeyData: Data)
typealias PublicKeyType = (publicKey: P256.KeyAgreement.PublicKey, publicKeyData: Data)

var enryptedMessage: EncryptedPushMessage?

init(message: [String: String]) throws {
do {
let data = try JSONSerialization.data(withJSONObject: message, options: .prettyPrinted)
self.enryptedMessage = try JSONDecoder().decode(EncryptedPushMessage.self, from: data)

} catch {
throw SecurityHelperError.initFailed(error: error.localizedDescription)
}
}

func getDecryptedMessage() throws -> String? {
do {
guard let enryptedMessage = enryptedMessage else {
return nil
}

let privateKeyType = try privateKey(from: enryptedMessage.privateKeyBase64)
let publicKeyType = try publicKey(from: enryptedMessage.publicKeyBase64)

guard let authSecretData = Data(base64Encoded: enryptedMessage.authBase64, options: .ignoreUnknownCharacters),
let authSecret = String(data: authSecretData, encoding: .utf8) else {
throw SecurityHelperError.authSecretGenerationFailed(error: "Could not generate Data or String from authBase64: \(enryptedMessage.authBase64)")
}

// let keysetHandle = TINKKeysetHandle()
// let hybridDecrypt: TINKHybridDecrypt = TINKHybridDecryptFactory

} catch {
throw SecurityHelperError.messageDecryptionFailed(error: error.localizedDescription)
}

return nil
}

func privateKey(from base64EncodedKey: String) throws -> PrivateKeyType {
do {
guard let data = Data(base64Encoded: base64EncodedKey, options: .ignoreUnknownCharacters) else {
throw SecurityHelperError.privateKeyGenerationFailed(error: "Could not generate Data from base64EncodedKey: \(base64EncodedKey)")
}

var result: PrivateKeyType
result.privateKey = try P256.KeyAgreement.PrivateKey(rawRepresentation: data)
result.privateKeyData = data

return result

} catch {
throw SecurityHelperError.privateKeyGenerationFailed(error: error.localizedDescription)
}
}

func publicKey(from base64EncodedKey: String) throws -> PublicKeyType {
do {
guard let data = Data(base64Encoded: base64EncodedKey, options: .ignoreUnknownCharacters) else {
throw SecurityHelperError.publicKeyGenerationFailed(error: "Could not generate Data from base64EncodedKey: \(base64EncodedKey)")
}

var result: PublicKeyType
result.publicKey = try P256.KeyAgreement.PublicKey(rawRepresentation: data)
result.publicKeyData = data

return result

} catch {
throw SecurityHelperError.publicKeyGenerationFailed(error: error.localizedDescription)
}
}

}

extension String {
var base64Decoded: String? {
get {
if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters),
let decodedString = String(data: data, encoding: .utf8) {
return decodedString
}
return nil
}
}
}

struct EncryptedPushMessage: Decodable {
let encryptedBase64Content: String
let privateKeyBase64: String
let publicKeyBase64: String
let authBase64: String
}

enum SecurityHelperError: Error {
case initFailed(error: String)
case messageDecryptionFailed(error: String)
case authSecretGenerationFailed(error: String)
case privateKeyGenerationFailed(error: String)
case publicKeyGenerationFailed(error: String)
}

10 changes: 9 additions & 1 deletion ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
platform :ios, '12.4'
platform :ios, '13.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down Expand Up @@ -31,6 +31,14 @@ def parse_KV_file(file, separator='=')
generated_key_values
end

target 'NotificationService' do
use_frameworks!
use_modular_headers!

pod 'Tink'
pod "GMEllipticCurveCrypto"
end

target 'Runner' do
use_frameworks!
use_modular_headers!
Expand Down
Loading

0 comments on commit 9cbc4b7

Please sign in to comment.