From 84c1058e8393b94208419f2651f55406f6bae2a3 Mon Sep 17 00:00:00 2001 From: Christian Risi <75698846+CnF-Gris@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:01:07 +0100 Subject: [PATCH] Added support to sign messages --- .devcontainer/devcontainer.json | 4 +- .../Classes/Devices/EdgeDevice.swift | 8 +-- .../Classes/Utils/Message.swift | 51 ++++++++++++++----- .../Protocols/Signable.swift | 0 .../IoT-Simulator-Core/Utils/Security.swift | 27 ++++++++-- .../IoT_Simulator_CoreTests.swift | 17 ++++--- 6 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 Sources/IoT-Simulator-Core/Protocols/Signable.swift diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2f7b112..0ddb622 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,8 +10,8 @@ "vscode": { "extensions": [ "sswg.swift-lang", - "fabiospampinato.vscode-highlight", - "fabiospampinato.vscode-todo-plus" + //"fabiospampinato.vscode-highlight", + //"fabiospampinato.vscode-todo-plus" ] } }, diff --git a/Sources/IoT-Simulator-Core/Classes/Devices/EdgeDevice.swift b/Sources/IoT-Simulator-Core/Classes/Devices/EdgeDevice.swift index bf42e8c..ea21933 100644 --- a/Sources/IoT-Simulator-Core/Classes/Devices/EdgeDevice.swift +++ b/Sources/IoT-Simulator-Core/Classes/Devices/EdgeDevice.swift @@ -1,4 +1,4 @@ -/* public class EdgeDevice : EdgeDeviceP { +public class EdgeDevice : EdgeDeviceP { public let deviceID: String public let deviceType: DeviceType @@ -56,8 +56,8 @@ // Todo: END Add Vincenzo's implementation return Message( - msgType: MessageType, - timestamp: Date, + msgType: MessageType.Data, + timestamp: , deviceID: String, location: Location3D, fields: [Field], @@ -70,4 +70,4 @@ -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/Sources/IoT-Simulator-Core/Classes/Utils/Message.swift b/Sources/IoT-Simulator-Core/Classes/Utils/Message.swift index ea1a731..63ac198 100644 --- a/Sources/IoT-Simulator-Core/Classes/Utils/Message.swift +++ b/Sources/IoT-Simulator-Core/Classes/Utils/Message.swift @@ -1,26 +1,51 @@ -import Foundation +import Crypto +import Foundation + public class Message { - - public let messageType : MessageType - public let timestamp : Date - public let deviceID : String - public let location : Location3D - public let fields : [Field] - public let signature : [UInt8] + + public let messageType: MessageType + public let timestamp: Date + public let deviceID: String + public let location: Location3D + public let fields: [Field] + public var signature: String { + get{ + return self._signature != nil ? self._signature! : "##INVALID" + } + } + private var _signature: String? = nil public init( msgType: MessageType, - timestamp: Date, + timestamp: Date, deviceID: String, location: Location3D, - fields: [Field], - signature: [UInt8] + fields: [Field] ) { self.messageType = msgType self.timestamp = timestamp self.deviceID = deviceID self.location = location self.fields = fields - self.signature = signature + } -} \ No newline at end of file + + public func toData() -> Data { + var string: String = "" + "\(messageType)" + "\(timestamp)" + "\(deviceID)" + "\(location)" + + for field in self.fields { + string += "\(field)" + } + + return Data(string.utf8) + } + + public func signMessage(key: P521.Signing.PrivateKey) { + do { + self._signature = try sign(object: self.toData(), key: key) + } catch { + // Do nothing + } + } + +} diff --git a/Sources/IoT-Simulator-Core/Protocols/Signable.swift b/Sources/IoT-Simulator-Core/Protocols/Signable.swift new file mode 100644 index 0000000..e69de29 diff --git a/Sources/IoT-Simulator-Core/Utils/Security.swift b/Sources/IoT-Simulator-Core/Utils/Security.swift index cd42d73..d7c5d81 100644 --- a/Sources/IoT-Simulator-Core/Utils/Security.swift +++ b/Sources/IoT-Simulator-Core/Utils/Security.swift @@ -1,13 +1,19 @@ import Crypto // Equivalent to CryptoKit (more or less) import Foundation + // ------------------ // --- Sign --------- // ------------------ public func sign(string: String, key: P521.Signing.PrivateKey) throws -> String { let data = Data(string.utf8) - return try key.signature(for: data).rawRepresentation + return try sign(object: data, key: key) + +} + +public func sign(object: Data, key: P521.Signing.PrivateKey)throws -> String { + return try key.signature(for: object).rawRepresentation.base64EncodedString() } @@ -17,13 +23,13 @@ public func sign(string: String, key: P521.Signing.PrivateKey) throws -> String // --- Decrypt ------ // ------------------ -public func verify(signature: String, string: String, key: P521.Signing.PublicKey) throws -> Bool { +public func verifySignature(signature: String, string: String, key: P521.Signing.PublicKey) throws -> Bool { let data = Data(string.utf8) let ecdsa: P521.Signing.ECDSASignature do { - let bytes = ecdsa - ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: signature) + let bytes = Data(base64Encoded: signature)! + ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: bytes) } catch { throw SecurityError.NotDecodableError } @@ -31,6 +37,19 @@ public func verify(signature: String, string: String, key: P521.Signing.PublicKe return key.isValidSignature(ecdsa, for: data) } +public func verifySignature(signature: String, object: Data, key: P521.Signing.PublicKey) throws -> Bool { + + let ecdsa: P521.Signing.ECDSASignature + do { + let bytes = Data(base64Encoded: signature)! + ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: bytes) + } catch { + throw SecurityError.NotDecodableError + } + + return key.isValidSignature(ecdsa, for: object) +} + // ------------------ diff --git a/Tests/IoT-Simulator-CoreTests/IoT_Simulator_CoreTests.swift b/Tests/IoT-Simulator-CoreTests/IoT_Simulator_CoreTests.swift index 3e939fb..5c0463a 100644 --- a/Tests/IoT-Simulator-CoreTests/IoT_Simulator_CoreTests.swift +++ b/Tests/IoT-Simulator-CoreTests/IoT_Simulator_CoreTests.swift @@ -1,7 +1,7 @@ import Testing import RandomCpp import Foundation -import SwiftASN1 +import Crypto @testable import IoT_Simulator_Core @@ -38,9 +38,10 @@ import SwiftASN1 let keyPath = "./Private/privateKey.pem" let key = try pem2key(filePath: keyPath) - let obj = [1, 2, 3] + let obj = "[1, 2, 3] " - let signature = try sign(object: obj, key: key) + let signature = try sign(string: obj, key: key) + print(signature) } @@ -49,10 +50,14 @@ import SwiftASN1 let keyPath = "./Private/privateKey.pem" let key = try pem2key(filePath: keyPath) - let obj = "[1, 2, 3]" + let obj = "[1, 2, 3] " - let signature = try sign(object: obj, key: key) + let signature = try sign(string: obj, key: key) + let puKey = key.publicKey - + let verify = try verify(signature: signature, string: obj, key: puKey) + print(verify) + assert(verify) } +