remove TaintedString (#3546)

* remove TaintedString

* dumpDir is used as a helper function for more specific types of dumpDirs
This commit is contained in:
tersec 2022-03-24 21:44:34 +00:00 committed by GitHub
parent e009728858
commit b37bf8c94b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 40 deletions

View File

@ -880,7 +880,7 @@ proc defaultDataDir*(config: AnyConf): string =
getHomeDir() / dataDir / "BeaconNode" getHomeDir() / dataDir / "BeaconNode"
func dumpDir*(config: AnyConf): string = func dumpDir(config: AnyConf): string =
config.dataDir / "dump" config.dataDir / "dump"
func dumpDirInvalid*(config: AnyConf): string = func dumpDirInvalid*(config: AnyConf): string =
@ -904,50 +904,50 @@ proc createDumpDirs*(config: BeaconNodeConf) =
warn "Could not create dump directory", warn "Could not create dump directory",
path = config.dumpDirOutgoing, err = ioErrorMsg(res.error) path = config.dumpDirOutgoing, err = ioErrorMsg(res.error)
func parseCmdArg*(T: type GraffitiBytes, input: TaintedString): T func parseCmdArg*(T: type GraffitiBytes, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
GraffitiBytes.init(string input) GraffitiBytes.init(input)
func completeCmdArg*(T: type GraffitiBytes, input: TaintedString): seq[string] = func completeCmdArg*(T: type GraffitiBytes, input: string): seq[string] =
return @[] return @[]
func parseCmdArg*(T: type BlockHashOrNumber, input: TaintedString): T func parseCmdArg*(T: type BlockHashOrNumber, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
init(BlockHashOrNumber, string input) init(BlockHashOrNumber, input)
func completeCmdArg*(T: type BlockHashOrNumber, input: TaintedString): seq[string] = func completeCmdArg*(T: type BlockHashOrNumber, input: string): seq[string] =
return @[] return @[]
func parseCmdArg*(T: type Uri, input: TaintedString): T func parseCmdArg*(T: type Uri, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
parseUri(input.string) parseUri(input)
func completeCmdArg*(T: type Uri, input: TaintedString): seq[string] = func completeCmdArg*(T: type Uri, input: string): seq[string] =
return @[] return @[]
func parseCmdArg*(T: type PubKey0x, input: TaintedString): T func parseCmdArg*(T: type PubKey0x, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
PubKey0x(hexToPaddedByteArray[RawPubKeySize](input.string)) PubKey0x(hexToPaddedByteArray[RawPubKeySize](input))
func parseCmdArg*(T: type ValidatorPubKey, input: TaintedString): T func parseCmdArg*(T: type ValidatorPubKey, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
let res = ValidatorPubKey.fromHex(input.string) let res = ValidatorPubKey.fromHex(input)
if res.isErr(): raise (ref ValueError)(msg: $res.error()) if res.isErr(): raise (ref ValueError)(msg: $res.error())
res.get() res.get()
func completeCmdArg*(T: type PubKey0x, input: TaintedString): seq[string] = func completeCmdArg*(T: type PubKey0x, input: string): seq[string] =
return @[] return @[]
func parseCmdArg*(T: type Checkpoint, input: TaintedString): T func parseCmdArg*(T: type Checkpoint, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
let sepIdx = find(input.string, ':') let sepIdx = find(input, ':')
if sepIdx == -1: if sepIdx == -1:
raise newException(ValueError, raise newException(ValueError,
"The weak subjectivity checkpoint must be provided in the `block_root:epoch_number` format") "The weak subjectivity checkpoint must be provided in the `block_root:epoch_number` format")
T(root: Eth2Digest.fromHex(input[0 ..< sepIdx]), T(root: Eth2Digest.fromHex(input[0 ..< sepIdx]),
epoch: parseBiggestUInt(input[sepIdx .. ^1]).Epoch) epoch: parseBiggestUInt(input[sepIdx .. ^1]).Epoch)
func completeCmdArg*(T: type Checkpoint, input: TaintedString): seq[string] = func completeCmdArg*(T: type Checkpoint, input: string): seq[string] =
return @[] return @[]
func isPrintable(rune: Rune): bool = func isPrintable(rune: Rune): bool =
@ -957,13 +957,13 @@ func isPrintable(rune: Rune): bool =
# https://github.com/nitely/nim-segmentation # https://github.com/nitely/nim-segmentation
rune == Rune(0x20) or unicodeCategory(rune) notin ctgC+ctgZ rune == Rune(0x20) or unicodeCategory(rune) notin ctgC+ctgZ
func parseCmdArg*(T: type WalletName, input: TaintedString): T func parseCmdArg*(T: type WalletName, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
if input.len == 0: if input.len == 0:
raise newException(ValueError, "The wallet name should not be empty") raise newException(ValueError, "The wallet name should not be empty")
if input[0] == '_': if input[0] == '_':
raise newException(ValueError, "The wallet name should not start with an underscore") raise newException(ValueError, "The wallet name should not start with an underscore")
for rune in runes(input.string): for rune in runes(input):
if not rune.isPrintable: if not rune.isPrintable:
raise newException(ValueError, "The wallet name should consist only of printable characters") raise newException(ValueError, "The wallet name should consist only of printable characters")
@ -972,15 +972,15 @@ func parseCmdArg*(T: type WalletName, input: TaintedString): T
# (see UTR #36 http://www.unicode.org/reports/tr36/) # (see UTR #36 http://www.unicode.org/reports/tr36/)
return T(toNFKC(input)) return T(toNFKC(input))
func completeCmdArg*(T: type WalletName, input: TaintedString): seq[string] = func completeCmdArg*(T: type WalletName, input: string): seq[string] =
return @[] return @[]
proc parseCmdArg*(T: type enr.Record, p: TaintedString): T proc parseCmdArg*(T: type enr.Record, p: string): T
{.raises: [ConfigurationError, Defect].} = {.raises: [ConfigurationError, Defect].} =
if not fromURI(result, p): if not fromURI(result, p):
raise newException(ConfigurationError, "Invalid ENR") raise newException(ConfigurationError, "Invalid ENR")
func completeCmdArg*(T: type enr.Record, val: TaintedString): seq[string] = func completeCmdArg*(T: type enr.Record, val: string): seq[string] =
return @[] return @[]
func validatorsDir*(config: AnyConf): string = func validatorsDir*(config: AnyConf): string =
@ -1062,7 +1062,7 @@ proc readValue*(r: var TomlReader, value: var GraffitiBytes)
proc readValue*(r: var TomlReader, val: var NatConfig) proc readValue*(r: var TomlReader, val: var NatConfig)
{.raises: [Defect, IOError, SerializationError].} = {.raises: [Defect, IOError, SerializationError].} =
val = try: parseCmdArg(NatConfig, TaintedString r.readValue(string)) val = try: parseCmdArg(NatConfig, r.readValue(string))
except CatchableError as err: except CatchableError as err:
raise newException(SerializationError, err.msg) raise newException(SerializationError, err.msg)
@ -1090,14 +1090,14 @@ proc readValue*(reader: var TomlReader, value: var ValidatorPubKey)
proc readValue*(r: var TomlReader, a: var PubKey0x) proc readValue*(r: var TomlReader, a: var PubKey0x)
{.raises: [Defect, IOError, SerializationError].} = {.raises: [Defect, IOError, SerializationError].} =
try: try:
a = parseCmdArg(PubKey0x, TaintedString r.readValue(string)) a = parseCmdArg(PubKey0x, r.readValue(string))
except CatchableError: except CatchableError:
r.raiseUnexpectedValue("a 0x-prefixed hex-encoded string expected") r.raiseUnexpectedValue("a 0x-prefixed hex-encoded string expected")
proc readValue*(r: var TomlReader, a: var WalletName) proc readValue*(r: var TomlReader, a: var WalletName)
{.raises: [Defect, IOError, SerializationError].} = {.raises: [Defect, IOError, SerializationError].} =
try: try:
a = parseCmdArg(WalletName, TaintedString r.readValue(string)) a = parseCmdArg(WalletName, r.readValue(string))
except CatchableError: except CatchableError:
r.raiseUnexpectedValue("string expected") r.raiseUnexpectedValue("string expected")

View File

@ -1,5 +1,5 @@
# beacon_chain # beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2022 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -231,7 +231,7 @@ proc main() {.async.} =
if conf.askForKey: if conf.askForKey:
var var
privateKey: TaintedString privateKey: string # TODO consider using a SecretString type
reasonForKey = "" reasonForKey = ""
if conf.cmd == StartUpCommand.sendDeposits: if conf.cmd == StartUpCommand.sendDeposits:

View File

@ -1,5 +1,5 @@
# beacon_chain # beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2022 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -23,7 +23,7 @@ export
Eth2DiscoveryProtocol, open, start, close, closeWait, queryRandom, Eth2DiscoveryProtocol, open, start, close, closeWait, queryRandom,
updateRecord, results updateRecord, results
proc parseBootstrapAddress*(address: TaintedString): proc parseBootstrapAddress*(address: string):
Result[enr.Record, cstring] = Result[enr.Record, cstring] =
logScope: logScope:
address = string(address) address = string(address)

View File

@ -1,5 +1,5 @@
# beacon_chain # beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH # Copyright (c) 2018-2022 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -239,7 +239,7 @@ template `$`*(x: WalletName): string =
# TODO: `burnMem` in nimcrypto could use distinctBase # TODO: `burnMem` in nimcrypto could use distinctBase
# to make its usage less error-prone. # to make its usage less error-prone.
template burnMem*(m: var (Mnemonic|TaintedString)) = template burnMem*(m: var (Mnemonic|string)) =
ncrutils.burnMem(string m) ncrutils.burnMem(string m)
template burnMem*(m: var KeySeed) = template burnMem*(m: var KeySeed) =
@ -291,7 +291,7 @@ proc checkEnglishWords(): bool =
static: static:
doAssert(checkEnglishWords(), "English words array is corrupted!") doAssert(checkEnglishWords(), "English words array is corrupted!")
func validateKeyPath*(path: TaintedString): Result[KeyPath, cstring] = func validateKeyPath*(path: string): Result[KeyPath, cstring] =
var digitCount: int var digitCount: int
var number: BiggestUint var number: BiggestUint
try: try:
@ -389,7 +389,7 @@ proc cmpIgnoreCase(lhs: cstring, rhs: string): int =
# Nim should have a `cmp` function for C strings. # Nim should have a `cmp` function for C strings.
cmpIgnoreCase($lhs, rhs) cmpIgnoreCase($lhs, rhs)
proc validateMnemonic*(inputWords: TaintedString, proc validateMnemonic*(inputWords: string,
outputMnemonic: var Mnemonic): bool = outputMnemonic: var Mnemonic): bool =
## Accept a case-insensitive input string and returns `true` ## Accept a case-insensitive input string and returns `true`
## if it represents a valid mnenomic. The `outputMnemonic` ## if it represents a valid mnenomic. The `outputMnemonic`
@ -400,6 +400,8 @@ proc validateMnemonic*(inputWords: TaintedString,
## with sensitive data even in case of validator failure. ## with sensitive data even in case of validator failure.
## Make sure to burn the received data after usage. ## Make sure to burn the received data after usage.
# TODO consider using a SecretString type for inputWords
let words = strutils.strip(inputWords.string.toNFKD).split(Whitespace) let words = strutils.strip(inputWords.string.toNFKD).split(Whitespace)
if words.len < 12 or words.len > 24 or words.len mod 3 != 0: if words.len < 12 or words.len > 24 or words.len mod 3 != 0:
return false return false

View File

@ -76,7 +76,7 @@ type
DEPOSIT_CONTRACT_ADDRESS*: Eth1Address DEPOSIT_CONTRACT_ADDRESS*: Eth1Address
PresetFile* = object PresetFile* = object
values*: Table[TaintedString, TaintedString] values*: Table[string, string]
missingValues*: seq[string] missingValues*: seq[string]
PresetFileError* = object of CatchableError PresetFileError* = object of CatchableError

View File

@ -1000,7 +1000,7 @@ proc saveWallet*(wallet: Wallet, outWalletPath: string): Result[void, string] =
proc saveWallet*(wallet: WalletPathPair): Result[void, string] = proc saveWallet*(wallet: WalletPathPair): Result[void, string] =
saveWallet(wallet.wallet, wallet.path) saveWallet(wallet.wallet, wallet.path)
proc readPasswordInput(prompt: string, password: var TaintedString): bool = proc readPasswordInput(prompt: string, password: var string): bool =
try: try:
when defined(windows): when defined(windows):
# readPasswordFromStdin() on Windows always returns `false`. # readPasswordFromStdin() on Windows always returns `false`.
@ -1038,7 +1038,7 @@ proc resetAttributesNoError() =
proc importKeystoresFromDir*(rng: var BrHmacDrbgContext, proc importKeystoresFromDir*(rng: var BrHmacDrbgContext,
importedDir, validatorsDir, secretsDir: string) = importedDir, validatorsDir, secretsDir: string) =
var password: TaintedString var password: string # TODO consider using a SecretString type
defer: burnMem(password) defer: burnMem(password)
try: try:
@ -1298,7 +1298,7 @@ proc createWalletInteractively*(
proc restoreWalletInteractively*(rng: var BrHmacDrbgContext, proc restoreWalletInteractively*(rng: var BrHmacDrbgContext,
config: BeaconNodeConf) = config: BeaconNodeConf) =
var var
enteredMnemonic: TaintedString enteredMnemonic: string
validatedMnemonic: Mnemonic validatedMnemonic: Mnemonic
defer: defer:

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2021-2022 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.} {.used.}
import import
@ -128,7 +135,7 @@ proc startSingleNodeNetwork =
"--output-bootstrap-file=" & bootstrapEnrFile, "--output-bootstrap-file=" & bootstrapEnrFile,
"--netkey-file=network_key.json", "--netkey-file=network_key.json",
"--insecure-netkey-password=true", "--insecure-netkey-password=true",
"--genesis-offset=0"], TaintedString it)) "--genesis-offset=0"], it))
doCreateTestnet(createTestnetConf, rng[]) doCreateTestnet(createTestnetConf, rng[])
@ -147,7 +154,7 @@ proc startSingleNodeNetwork =
"--keymanager-address=127.0.0.1", "--keymanager-address=127.0.0.1",
"--keymanager-port=" & $keymanagerPort, "--keymanager-port=" & $keymanagerPort,
"--keymanager-token-file=" & tokenFilePath, "--keymanager-token-file=" & tokenFilePath,
"--doppelganger-detection=off"], TaintedString it)) "--doppelganger-detection=off"], it))
let metadata = loadEth2NetworkMetadata(dataDir) let metadata = loadEth2NetworkMetadata(dataDir)