Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ xcuserdata
MoppApp/GoogleService-Info.plist
MoppApp/MoppApp/config.json
MoppApp/MoppApp/defaultConfiguration.json
MoppApp/MoppApp/publicKey.pub
MoppApp/MoppApp/signature.rsa
MoppApp/MoppApp/publicKey.ecpub
MoppApp/MoppApp/signature.ecc
16 changes: 8 additions & 8 deletions MoppApp/MoppApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,9 @@
DFF3C3B22332314A0079458A /* RuntimeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF3C3B02332314A0079458A /* RuntimeError.swift */; };
DFF3C3B32332314A0079458A /* SignatureVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF3C3B12332314A0079458A /* SignatureVerifier.swift */; };
DFF3C3B5233231F20079458A /* Notification+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFF3C3B4233231F20079458A /* Notification+Additions.swift */; };
DFF3C3BC2332355D0079458A /* publicKey.pub in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3B82332355C0079458A /* publicKey.pub */; };
DFF3C3BC2332355D0079458A /* publicKey.ecpub in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3B82332355C0079458A /* publicKey.ecpub */; };
DFF3C3BD2332355D0079458A /* config.json in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3B92332355C0079458A /* config.json */; };
DFF3C3BE2332355D0079458A /* signature.rsa in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3BA2332355C0079458A /* signature.rsa */; };
DFF3C3BE2332355D0079458A /* signature.ecc in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3BA2332355C0079458A /* signature.ecc */; };
DFF3C3BF2332355D0079458A /* defaultConfiguration.json in Resources */ = {isa = PBXBuildFile; fileRef = DFF3C3BB2332355D0079458A /* defaultConfiguration.json */; };
E4250CCB1E0968D200530370 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4250CCA1E0968D200530370 /* AppDelegate.swift */; };
E4250D0A1E0AA7AF00530370 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = E4250D091E0AA7AF00530370 /* LaunchScreen.xib */; };
Expand Down Expand Up @@ -570,9 +570,9 @@
DFF3C3B02332314A0079458A /* RuntimeError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuntimeError.swift; sourceTree = "<group>"; };
DFF3C3B12332314A0079458A /* SignatureVerifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignatureVerifier.swift; sourceTree = "<group>"; };
DFF3C3B4233231F20079458A /* Notification+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Notification+Additions.swift"; sourceTree = "<group>"; };
DFF3C3B82332355C0079458A /* publicKey.pub */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = publicKey.pub; path = MoppApp/publicKey.pub; sourceTree = "<group>"; };
DFF3C3B82332355C0079458A /* publicKey.ecpub */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = publicKey.ecpub; path = MoppApp/publicKey.ecpub; sourceTree = "<group>"; };
DFF3C3B92332355C0079458A /* config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = config.json; path = MoppApp/config.json; sourceTree = "<group>"; };
DFF3C3BA2332355C0079458A /* signature.rsa */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = signature.rsa; path = MoppApp/signature.rsa; sourceTree = "<group>"; };
DFF3C3BA2332355C0079458A /* signature.ecc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = signature.ecc; path = MoppApp/signature.ecc; sourceTree = "<group>"; };
DFF3C3BB2332355D0079458A /* defaultConfiguration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = defaultConfiguration.json; path = MoppApp/defaultConfiguration.json; sourceTree = "<group>"; };
DFF6A55627E14D3B0055F8D5 /* RoleDetailsViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoleDetailsViewControllerTests.swift; sourceTree = "<group>"; };
E4250CC31E0968D200530370 /* MoppApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MoppApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -1048,8 +1048,8 @@
DFB1D5EA2ACAFE1B00FDC7B8 /* GoogleService-Info.plist */,
DFF3C3B92332355C0079458A /* config.json */,
DFF3C3BB2332355D0079458A /* defaultConfiguration.json */,
DFF3C3B82332355C0079458A /* publicKey.pub */,
DFF3C3BA2332355C0079458A /* signature.rsa */,
DFF3C3B82332355C0079458A /* publicKey.ecpub */,
DFF3C3BA2332355C0079458A /* signature.ecc */,
E4250CC51E0968D200530370 /* MoppApp */,
54A418251E83FAD200559E2B /* shareExtension */,
DFF6A54E27E14C180055F8D5 /* MoppAppTests */,
Expand Down Expand Up @@ -1378,8 +1378,8 @@
DFB1D5EB2ACAFE1B00FDC7B8 /* GoogleService-Info.plist in Resources */,
DFF3C3BF2332355D0079458A /* defaultConfiguration.json in Resources */,
DFF3C3BD2332355D0079458A /* config.json in Resources */,
DFF3C3BE2332355D0079458A /* signature.rsa in Resources */,
DFF3C3BC2332355D0079458A /* publicKey.pub in Resources */,
DFF3C3BE2332355D0079458A /* signature.ecc in Resources */,
DFF3C3BC2332355D0079458A /* publicKey.ecpub in Resources */,
DF900C972386768F00887385 /* tslFiles.bundle in Resources */,
DFC2ADC329437790008A1CD2 /* Accessibility.storyboard in Resources */,
C50DCD011FC6E97400D48E16 /* Container.storyboard in Resources */,
Expand Down
10 changes: 5 additions & 5 deletions MoppApp/MoppApp/SettingsConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class SettingsConfiguration: NSObject, URLSessionDelegate, URLSessionTaskDelegat
internal func loadLocalConfiguration() {
do {
let localConfigData = try String(contentsOfFile: Bundle.main.path(forResource: "config", ofType: "json")!)
let localSignature = try String(contentsOfFile: Bundle.main.path(forResource: "signature", ofType: "rsa")!)
let localSignature = try String(contentsOfFile: Bundle.main.path(forResource: "signature", ofType: "ecc")!)
let decodedData = try MOPPConfiguration(json: localConfigData)
setAllConfigurationToCache(configData: localConfigData, signature: localSignature, initialUpdateDate: MoppDateFormatter().stringToDate(dateString: getDefaultMoppConfiguration().UPDATEDATE), versionSerial: decodedData.METAINF.SERIAL)
setConfigurationToCache("", forKey: "lastUpdateDateCheck")
Expand All @@ -119,7 +119,7 @@ class SettingsConfiguration: NSObject, URLSessionDelegate, URLSessionTaskDelegat
internal func loadCachedConfiguration() {
do {
let cachedConfigData = getConfigurationFromCache(forKey: "config") as! String
let localPublicKey = try String(contentsOfFile: Bundle.main.path(forResource: "publicKey", ofType: "pub")!)
let localPublicKey = try String(contentsOfFile: Bundle.main.path(forResource: "publicKey", ofType: "ecpub")!)
let cachedSignature = getConfigurationFromCache(forKey: "signature") as! String

_ = try SignatureVerifier.isSignatureCorrect(configData: cachedConfigData, publicKey: localPublicKey, signature: cachedSignature)
Expand Down Expand Up @@ -152,14 +152,14 @@ class SettingsConfiguration: NSObject, URLSessionDelegate, URLSessionTaskDelegat
internal func loadCentralConfiguration(completionHandler: @escaping (Error) -> () = { _ in }) {
do {
let cachedSignature = getConfigurationFromCache(forKey: "signature") as? String
let localPublicKey = try String(contentsOfFile: Bundle.main.path(forResource: "publicKey", ofType: "pub")!)
let localPublicKey = try String(contentsOfFile: Bundle.main.path(forResource: "publicKey", ofType: "ecpub")!)

if isInitialSetup() {
setConfigurationToCache(true, forKey: "isCentralConfigurationLoaded")
loadCachedConfiguration()
}

getFetchedData(fromUrl: "\(getDefaultMoppConfiguration().CENTRALCONFIGURATIONSERVICEURL)/config.rsa") { (centralSignature, signatureError) in
getFetchedData(fromUrl: "\(getDefaultMoppConfiguration().CENTRALCONFIGURATIONSERVICEURL)/config.ecc") { (centralSignature, signatureError) in
if let error = signatureError {
printLog(error.localizedDescription)
return completionHandler(error)
Expand Down
34 changes: 19 additions & 15 deletions MoppApp/MoppApp/SignatureVerifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*
*/

import Security
import CryptoKit

class SignatureVerifier {

Expand All @@ -30,24 +30,28 @@ class SignatureVerifier {
throw Exception("Invalid signature")
}
guard let pubKey = fromBase64(publicKey
.replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "-----END RSA PUBLIC KEY-----", with: "")) else {
.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "-----END PUBLIC KEY-----", with: "")) else {
throw Exception("Invalid public key")
}
let parameters: [CFString: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPublic,
kSecReturnPersistentRef: false
]
var error: Unmanaged<CFError>?
guard let key = SecKeyCreateWithData(pubKey as CFData, parameters as CFDictionary, &error) else {
printLog("Failed to create key: \(error!.takeRetainedValue())")
throw Exception("Failed to create key: \(error!.takeRetainedValue())")
let result: Bool
switch pubKey.count {
case 80...100:
let key = try P256.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P256.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
case 110...130:
let key = try P384.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P384.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
case 150...170:
let key = try P521.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P521.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
default:
throw Exception("Unknown key size")
}
let algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA512
let result = SecKeyVerifySignature(key, algorithm, Data(configData.utf8) as CFData, sigData as CFData, &error)
if !result {
print("Verification error: \(error!.takeRetainedValue())")
throw Exception("Signature verification unsuccessful")
}
}
Expand Down
18 changes: 7 additions & 11 deletions MoppApp/SetupConfiguration/Package.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
// swift-tools-version:4.2
import PackageDescription

let package = Package(name: "SetupConfiguration")

package.products = [
.executable(name: "SetupConfiguration", targets: ["SetupConfiguration"])
]
package.dependencies = [

]
package.targets = [
.target(name: "SetupConfiguration", dependencies: [], path: "Sources")
]
let package = Package(
name: "SetupConfiguration",
platforms: [.macOS(.v11)],
products: [.executable(name: "SetupConfiguration", targets: ["SetupConfiguration"])],
dependencies: [],
targets: [.target(name: "SetupConfiguration", dependencies: [], path: "Sources")],
)
44 changes: 26 additions & 18 deletions MoppApp/SetupConfiguration/Sources/main.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/swift sh

import Foundation
import Security
import CryptoKit

// MARK: - Settings Configuration

Expand All @@ -26,8 +26,8 @@ class SettingsConfiguration {

log("1 / 4 - Downloading configuration data...")
let configData = try fetchData(from: "\(configBaseUrl)/config.json")
let publicKey = try fetchData(from: "\(configBaseUrl)/config.pub")
let signature = try fetchData(from: "\(configBaseUrl)/config.rsa")
let publicKey = try fetchData(from: "\(configBaseUrl)/config.ecpub")
let signature = try fetchData(from: "\(configBaseUrl)/config.ecc")

log("2 / 4 - Verifying signature...")
try verifySignature(configData: configData, publicKey: publicKey, signature: signature)
Expand All @@ -38,8 +38,8 @@ class SettingsConfiguration {

log("4 / 4 - Saving and moving files...")
try saveFile(named: "config.json", content: configData)
try saveFile(named: "publicKey.pub", content: publicKey)
try saveFile(named: "signature.rsa", content: signature)
try saveFile(named: "publicKey.ecpub", content: publicKey)
try saveFile(named: "signature.ecc", content: signature)
try saveFile(named: "defaultConfiguration.json", content: defaultConfiguration)

log("Default configuration initialized successfully!")
Expand All @@ -64,27 +64,35 @@ extension SettingsConfiguration {
throw ConfigurationError.signatureVerificationFailed
}
guard let pubKey = Data(base64Encoded: publicKey
.replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "-----END RSA PUBLIC KEY-----", with: ""), options: .ignoreUnknownCharacters) else {
.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----", with: "")
.replacingOccurrences(of: "-----END PUBLIC KEY-----", with: ""), options: .ignoreUnknownCharacters) else {
log("Failed to parse key")
throw ConfigurationError.signatureVerificationFailed
}
guard let sigData = Data(base64Encoded: signature, options: .ignoreUnknownCharacters) else {
throw ConfigurationError.signatureVerificationFailed
}
let parameters: [CFString: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPublic,
kSecReturnPersistentRef: false
]
var error: Unmanaged<CFError>?
guard let key = SecKeyCreateWithData(pubKey as CFData, parameters as CFDictionary, &error) else {
log("Key importing failed \(error?.takeRetainedValue().localizedDescription ?? "")")

let result: Bool
switch pubKey.count {
case 80...100:
let key = try P256.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P256.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
case 110...130:
let key = try P384.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P384.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
case 150...170:
let key = try P521.Signing.PublicKey(derRepresentation: pubKey)
let sig = try P521.Signing.ECDSASignature(derRepresentation: sigData)
result = key.isValidSignature(sig, for: Data(configData.utf8))
default:
log("Unknown key size")
throw ConfigurationError.signatureVerificationFailed
}
let algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA512
let result = SecKeyVerifySignature(key, algorithm, Data(configData.utf8) as CFData, sigData as CFData, &error)
if !result {
log("Signature verifying failed \(error?.takeRetainedValue().localizedDescription ?? "")")
log("Signature verifying failed")
throw ConfigurationError.signatureVerificationFailed
}
log("Signature verified successfully!")
Expand Down