67 lines
2.0 KiB
Nim
Raw Permalink Normal View History

2025-02-06 10:16:47 +01:00
import pkg/chronicles
import pkg/questionable/results
import pkg/libp2p/crypto/crypto
import pkg/stew/io2
# This file is copied from nim-codex `codex/utils/keyutils.nim`
import ./rng
# from errors.nim:
template mapFailure*[T, V, E](
exp: Result[T, V], exc: typedesc[E]
): Result[T, ref CatchableError] =
## Convert `Result[T, E]` to `Result[E, ref CatchableError]`
##
exp.mapErr(
proc(e: V): ref CatchableError =
(ref exc)(msg: $e)
)
# from fileutils.nim
when defined(windows):
import stew/[windows/acl]
proc secureWriteFile*[T: byte | char](
path: string, data: openArray[T]
): IoResult[void] =
when defined(windows):
let sres = createFilesUserOnlySecurityDescriptor()
if sres.isErr():
error "Could not allocate security descriptor",
path = path, errorMsg = ioErrorMsg(sres.error), errorCode = $sres.error
err(sres.error)
else:
var sd = sres.get()
writeFile(path, data, 0o600, secDescriptor = sd.getDescriptor())
else:
writeFile(path, data, 0o600)
proc checkSecureFile*(path: string): IoResult[bool] =
when defined(windows):
checkCurrentUserOnlyACL(path)
else:
ok (?getPermissionsSet(path) == {UserRead, UserWrite})
2025-02-06 10:33:11 +01:00
type KeyError* = object of CatchableError
2025-02-06 10:16:47 +01:00
proc setupKey*(path: string): ?!PrivateKey =
if not path.fileAccessible({AccessFlags.Find}):
info "Creating a private key and saving it"
let
2025-02-07 13:57:57 +01:00
res =
?PrivateKey.random(PKScheme.Secp256k1, Rng.instance()[]).mapFailure(KeyError)
2025-02-06 10:16:47 +01:00
bytes = ?res.getBytes().mapFailure(KeyError)
?path.secureWriteFile(bytes).mapFailure(KeyError)
return PrivateKey.init(bytes).mapFailure(KeyError)
info "Found a network private key"
if not ?checkSecureFile(path).mapFailure(KeyError):
warn "The network private key file is not safe, aborting"
2025-02-06 10:33:11 +01:00
return failure newException(KeyError, "The network private key file is not safe")
2025-02-06 10:16:47 +01:00
let kb = ?path.readAllBytes().mapFailure(KeyError)
return PrivateKey.init(kb).mapFailure(KeyError)