Added initial support for signature
This commit is contained in:
parent
44d6d9a84f
commit
0eb4c0069e
@ -9,7 +9,9 @@
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"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(
|
||||
name: "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 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.
|
||||
.target(
|
||||
name: "RandomCpp"
|
||||
),
|
||||
|
||||
.target(
|
||||
name: "IoT-Simulator-Core",
|
||||
dependencies: [
|
||||
"RandomCpp",
|
||||
.product(name: "Crypto", package: "swift-crypto"),
|
||||
|
||||
],
|
||||
swiftSettings: [
|
||||
.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 _stdNoise: Float
|
||||
private let _quantizationBits: Int
|
||||
// TODO: add a generator of GaussianRNG
|
||||
//private var gaussianNoise:
|
||||
|
||||
public init(
|
||||
@ -90,7 +91,7 @@ public class RealSensor: Sensor {
|
||||
|
||||
override public func read(_ environment: PhysicalEnvironment) -> PhysicalData {
|
||||
let value: PhysicalData = super.read(environment)
|
||||
|
||||
// TODO Add gaussian error here
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
public class Field {
|
||||
|
||||
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 deviceType : DeviceType {get}
|
||||
var dataType : DataType {get}
|
||||
var disconnected : Bool {get set}
|
||||
var compromised : Bool {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 RandomCpp
|
||||
import Foundation
|
||||
import SwiftASN1
|
||||
|
||||
@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.
|
||||
var a = GaussianRNG(10, 0.5)
|
||||
|
||||
@ -11,3 +13,46 @@ import RandomCpp
|
||||
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