Added initial support for signature
This commit is contained in:
parent
44d6d9a84f
commit
0eb4c0069e
@ -9,7 +9,9 @@
|
|||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"sswg.swift-lang"
|
"sswg.swift-lang",
|
||||||
|
"fabiospampinato.vscode-highlight",
|
||||||
|
"fabiospampinato.vscode-todo-plus"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
24
Package.resolved
Normal file
24
Package.resolved
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"originHash" : "a49eafc65c63e9300677cadad384d86aab484d1c10a415ec467d840aff87c075",
|
||||||
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "swift-asn1",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-asn1.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "7faebca1ea4f9aaf0cda1cef7c43aecd2311ddf6",
|
||||||
|
"version" : "1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-crypto",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-crypto.git",
|
||||||
|
"state" : {
|
||||||
|
"branch" : "main",
|
||||||
|
"revision" : "dc4c2c14e7ff95ee3aa8d3c2a217a248f51d3688"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version" : 3
|
||||||
|
}
|
||||||
@ -10,20 +10,29 @@ let package = Package(
|
|||||||
.library(
|
.library(
|
||||||
name: "IoT-Simulator-Core",
|
name: "IoT-Simulator-Core",
|
||||||
targets: ["IoT-Simulator-Core"]
|
targets: ["IoT-Simulator-Core"]
|
||||||
),
|
),
|
||||||
.library(name: "RandomCpp", targets: ["RandomCpp"])
|
.library(
|
||||||
|
name: "RandomCpp",
|
||||||
|
targets: ["RandomCpp"]
|
||||||
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
dependencies: [],
|
dependencies: [
|
||||||
|
.package(url: "https://github.com/apple/swift-crypto.git", branch: "main"),
|
||||||
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
// Targets are the basic building blocks of a package, defining a module or a test suite.
|
||||||
// Targets can depend on other targets in this package and products from dependencies.
|
// Targets can depend on other targets in this package and products from dependencies.
|
||||||
.target(
|
.target(
|
||||||
name: "RandomCpp"
|
name: "RandomCpp"
|
||||||
),
|
),
|
||||||
|
|
||||||
.target(
|
.target(
|
||||||
name: "IoT-Simulator-Core",
|
name: "IoT-Simulator-Core",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"RandomCpp",
|
"RandomCpp",
|
||||||
|
.product(name: "Crypto", package: "swift-crypto"),
|
||||||
|
|
||||||
],
|
],
|
||||||
swiftSettings: [
|
swiftSettings: [
|
||||||
.interoperabilityMode(.Cxx)
|
.interoperabilityMode(.Cxx)
|
||||||
|
|||||||
16
Private/cert.pem
Normal file
16
Private/cert.pem
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICeTCCAdqgAwIBAgIUeKyiiDJdVGH3ParIry5vn/YGnaowCgYIKoZIzj0EAwIw
|
||||||
|
TjELMAkGA1UEBhMCSVQxDTALBgNVBAgMBEJhcmkxDTALBgNVBAcMBEJhcmkxITAf
|
||||||
|
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMDIxNjM0NDVa
|
||||||
|
Fw0yNTAxMDExNjM0NDVaME4xCzAJBgNVBAYTAklUMQ0wCwYDVQQIDARCYXJpMQ0w
|
||||||
|
CwYDVQQHDARCYXJpMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQw
|
||||||
|
gZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAAAfWnGEUMElY/XIWUTPvX65HX3N5Ik
|
||||||
|
JKPdVFzDRtaTHRJKnEEvU7Z5iLAT9NpbVfCabvQXKo7LD5sjoJ1ZpSVcogDgCFCo
|
||||||
|
pmVin2ZLs5lyMtaetpVDH8m+AIlRQkkuGmkasM+OV62kzSoHl/CL4eNz1xXwqsPt
|
||||||
|
oBgvPiRFxNIE/0dz96NTMFEwHQYDVR0OBBYEFKW5mYrSXJn68diXLDjhbiEGAxJu
|
||||||
|
MB8GA1UdIwQYMBaAFKW5mYrSXJn68diXLDjhbiEGAxJuMA8GA1UdEwEB/wQFMAMB
|
||||||
|
Af8wCgYIKoZIzj0EAwIDgYwAMIGIAkIAhVgtxgnZd6KeefLjZ6Mazgr5xLDcAHyI
|
||||||
|
NsKtTw3YzT/Pztnk2ccV+NyDZyoTG72lHoPMTiB5mRSUTqORg59XQTkCQgDqHRoN
|
||||||
|
tRQlPWY3abohilRRdvYZrsoPR8FzB/M4KxT0nk10jc1wtosQ7l/XZGcKe8/k+iVs
|
||||||
|
HC5CsESzsvnp+Qslyw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
7
Private/privateKey.pem
Normal file
7
Private/privateKey.pem
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIHcAgEBBEIBAQAy+3ElWUTttb9xxVDshJlGt/clGdhPkp76aJ3LJySugsnC8RRO
|
||||||
|
UracnWQi2A+XnEI1ZskzYAFUfh7G5o5ViDygBwYFK4EEACOhgYkDgYYABAAAfWnG
|
||||||
|
EUMElY/XIWUTPvX65HX3N5IkJKPdVFzDRtaTHRJKnEEvU7Z5iLAT9NpbVfCabvQX
|
||||||
|
Ko7LD5sjoJ1ZpSVcogDgCFCopmVin2ZLs5lyMtaetpVDH8m+AIlRQkkuGmkasM+O
|
||||||
|
V62kzSoHl/CL4eNz1xXwqsPtoBgvPiRFxNIE/0dz9w==
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
8
Private/privateKey_ASN1.pem
Normal file
8
Private/privateKey_ASN1.pem
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBAQAy+3ElWUTttb9x
|
||||||
|
xVDshJlGt/clGdhPkp76aJ3LJySugsnC8RROUracnWQi2A+XnEI1ZskzYAFUfh7G
|
||||||
|
5o5ViDyhgYkDgYYABAAAfWnGEUMElY/XIWUTPvX65HX3N5IkJKPdVFzDRtaTHRJK
|
||||||
|
nEEvU7Z5iLAT9NpbVfCabvQXKo7LD5sjoJ1ZpSVcogDgCFCopmVin2ZLs5lyMtae
|
||||||
|
tpVDH8m+AIlRQkkuGmkasM+OV62kzSoHl/CL4eNz1xXwqsPtoBgvPiRFxNIE/0dz
|
||||||
|
9w==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
2
Scripts/openssl-ecdsa-certs.sh
Normal file
2
Scripts/openssl-ecdsa-certs.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
openssl ecparam -name secp521r1 -genkey -noout -out privateKey.pem
|
||||||
|
openssl req -x509 -sha256 -key privateKey.pem -out cert.pem -nodes
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/* public class EdgeDevice : EdgeDeviceP {
|
||||||
|
|
||||||
|
public let deviceID: String
|
||||||
|
public let deviceType: DeviceType
|
||||||
|
public let dataType: DataType
|
||||||
|
public var disconnected: Bool
|
||||||
|
public var compromised: Bool
|
||||||
|
public var dutyCicle: UInt
|
||||||
|
public var sensors: [Int: Sensor]
|
||||||
|
public var privateKey: [UInt8]
|
||||||
|
|
||||||
|
private var numberOfSensors: Int {
|
||||||
|
get{
|
||||||
|
return sensors.count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(
|
||||||
|
deviceID: String,
|
||||||
|
dataType: DataType,
|
||||||
|
disconnected: Bool,
|
||||||
|
dutyCicle: UInt,
|
||||||
|
sensors: [Int: Sensor]
|
||||||
|
) {
|
||||||
|
self.deviceID = deviceID
|
||||||
|
self.deviceType = DeviceType.EdgeDevice
|
||||||
|
self.dataType = dataType
|
||||||
|
self.disconnected = disconnected
|
||||||
|
self.compromised = false
|
||||||
|
self.dutyCicle = dutyCicle
|
||||||
|
self.sensors = sensors
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addSensor(sensor: Sensor) {
|
||||||
|
self.sensors[numberOfSensors + 1] = sensor
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removeSensor(id: Int) {
|
||||||
|
self.sensors.removeValue(forKey: id)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func work(envrionment: PhysicalEnvironment) {
|
||||||
|
|
||||||
|
// UGLY: In case I have some optimization problems, fix here
|
||||||
|
var values: [Float] = []
|
||||||
|
|
||||||
|
for sensor in sensors {
|
||||||
|
values.append(
|
||||||
|
sensor.value.read(envrionment).value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: START Remove this and Add Vincenzo's implementation
|
||||||
|
let avg : Float = meanValue(values: values)
|
||||||
|
let std_dev : Float = standardDeviation(values: values)
|
||||||
|
|
||||||
|
// Todo: END Add Vincenzo's implementation
|
||||||
|
return Message(
|
||||||
|
msgType: MessageType,
|
||||||
|
timestamp: Date,
|
||||||
|
deviceID: String,
|
||||||
|
location: Location3D,
|
||||||
|
fields: [Field],
|
||||||
|
signature: [UInt8]
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} */
|
||||||
@ -59,6 +59,7 @@ public class RealSensor: Sensor {
|
|||||||
private var _meanNoise: Float
|
private var _meanNoise: Float
|
||||||
private var _stdNoise: Float
|
private var _stdNoise: Float
|
||||||
private let _quantizationBits: Int
|
private let _quantizationBits: Int
|
||||||
|
// TODO: add a generator of GaussianRNG
|
||||||
//private var gaussianNoise:
|
//private var gaussianNoise:
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
@ -90,7 +91,7 @@ public class RealSensor: Sensor {
|
|||||||
|
|
||||||
override public func read(_ environment: PhysicalEnvironment) -> PhysicalData {
|
override public func read(_ environment: PhysicalEnvironment) -> PhysicalData {
|
||||||
let value: PhysicalData = super.read(environment)
|
let value: PhysicalData = super.read(environment)
|
||||||
|
// TODO Add gaussian error here
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
public class Field {
|
public class Field {
|
||||||
|
|
||||||
public let key: String
|
public let key: String
|
||||||
|
|||||||
4
Sources/IoT-Simulator-Core/Errors/SecurityErrors.swift
Normal file
4
Sources/IoT-Simulator-Core/Errors/SecurityErrors.swift
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
enum SecurityError: Error {
|
||||||
|
case NotEncodableError
|
||||||
|
case NotDecodableError
|
||||||
|
}
|
||||||
@ -1,11 +1,13 @@
|
|||||||
public protocol EdgeDevice {
|
public protocol EdgeDeviceP {
|
||||||
|
|
||||||
var deviceID : String {get}
|
var deviceID : String {get}
|
||||||
var deviceType : DeviceType {get}
|
var deviceType : DeviceType {get}
|
||||||
var dataType : DataType {get}
|
var dataType : DataType {get}
|
||||||
var disconnected : Bool {get set}
|
var disconnected : Bool {get set}
|
||||||
var compromised : Bool {get set}
|
var compromised : Bool {get set}
|
||||||
var dutyCicle : UInt {get set}
|
var dutyCicle : UInt {get set}
|
||||||
|
var privateKey: [UInt8] {get}
|
||||||
|
|
||||||
func work() -> Message
|
func work(envrionment: PhysicalEnvironment) -> Message
|
||||||
|
|
||||||
}
|
}
|
||||||
55
Sources/IoT-Simulator-Core/Utils/Security.swift
Normal file
55
Sources/IoT-Simulator-Core/Utils/Security.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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<Data>(for: data).rawRepresentation
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// --- Decrypt ------
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
public func verify(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)
|
||||||
|
} catch {
|
||||||
|
throw SecurityError.NotDecodableError
|
||||||
|
}
|
||||||
|
|
||||||
|
return key.isValidSignature<Data>(ecdsa, for: data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// --- PEM 2 Key ----
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
public func pem2key(filePath: String) throws -> P521.Signing.PrivateKey {
|
||||||
|
|
||||||
|
let pemURL: URL = URL(filePath: filePath)
|
||||||
|
|
||||||
|
return try pem2key(filePem: pemURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func pem2key(filePem: URL) throws -> P521.Signing.PrivateKey {
|
||||||
|
|
||||||
|
let fileString: String = try String(contentsOf: filePem, encoding: String.Encoding.utf8)
|
||||||
|
return try pem2key(pemString: fileString)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func pem2key(pemString: String) throws -> P521.Signing.PrivateKey {
|
||||||
|
return try P521.Signing.PrivateKey(pemRepresentation: pemString)
|
||||||
|
}
|
||||||
28
Sources/IoT-Simulator-Core/Utils/Statistics.swift
Normal file
28
Sources/IoT-Simulator-Core/Utils/Statistics.swift
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public func meanValue<Numerical: FloatingPoint>(values: [Numerical]) -> Numerical{
|
||||||
|
var avg : Numerical = 0
|
||||||
|
|
||||||
|
for i in 0..<values.count {
|
||||||
|
avg += values[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return avg / Numerical(values.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UGLY Find a way to implement power protocol, if issues with optimization
|
||||||
|
public func standardDeviation<Numerical: FloatingPoint>(values: [Numerical]) -> Numerical{
|
||||||
|
|
||||||
|
let avg : Numerical = meanValue(values: values)
|
||||||
|
var summatory: Numerical = 0
|
||||||
|
|
||||||
|
for i in 0..<values.count {
|
||||||
|
let intermediate = (values[i] - avg)
|
||||||
|
summatory += (intermediate * intermediate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqrt(
|
||||||
|
summatory / Numerical(values.count)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
import Testing
|
import Testing
|
||||||
import RandomCpp
|
import RandomCpp
|
||||||
|
import Foundation
|
||||||
|
import SwiftASN1
|
||||||
|
|
||||||
@testable import IoT_Simulator_Core
|
@testable import IoT_Simulator_Core
|
||||||
|
|
||||||
@Test func example() async throws {
|
@Test func workingGeneratorTest() async throws {
|
||||||
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
var a = GaussianRNG(10, 0.5)
|
var a = GaussianRNG(10, 0.5)
|
||||||
|
|
||||||
@ -11,3 +13,46 @@ import RandomCpp
|
|||||||
print(a.generate())
|
print(a.generate())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test func pemDecoded() async throws {
|
||||||
|
/*
|
||||||
|
Even though here you would expect both texts to be equal,
|
||||||
|
the openssl generated one (the raw string) is ANSI x9.62
|
||||||
|
while ours (the one made with the library) is ASN.1
|
||||||
|
|
||||||
|
When inspected with openssl, both curves where identical,
|
||||||
|
so no need to be worried
|
||||||
|
*/
|
||||||
|
let keyPath = "./Private/privateKey.pem"
|
||||||
|
|
||||||
|
let url = URL(filePath: keyPath)
|
||||||
|
let pemString = try String(contentsOf: url, encoding: String.Encoding.utf8)
|
||||||
|
|
||||||
|
|
||||||
|
let key = try pem2key(filePath: keyPath)
|
||||||
|
print(pemString)
|
||||||
|
print(key.pemRepresentation)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func sign() async throws {
|
||||||
|
let keyPath = "./Private/privateKey.pem"
|
||||||
|
let key = try pem2key(filePath: keyPath)
|
||||||
|
|
||||||
|
let obj = [1, 2, 3]
|
||||||
|
|
||||||
|
let signature = try sign(object: obj, key: key)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func verifySignature() async throws {
|
||||||
|
let keyPath = "./Private/privateKey.pem"
|
||||||
|
let key = try pem2key(filePath: keyPath)
|
||||||
|
|
||||||
|
let obj = "[1, 2, 3]"
|
||||||
|
|
||||||
|
let signature = try sign(object: obj, key: key)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user