fix: fixed multiple bare except warnings

This commit is contained in:
Lorenzo Delgado 2023-04-04 15:34:53 +02:00 committed by GitHub
parent 7c229ece3b
commit caf78249b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 140 additions and 140 deletions

View File

@ -339,7 +339,7 @@ when isMainModule:
# Adhere to NO_COLOR initiative: https://no-color.org/ # Adhere to NO_COLOR initiative: https://no-color.org/
let color = try: not parseBool(os.getEnv("NO_COLOR", "false")) let color = try: not parseBool(os.getEnv("NO_COLOR", "false"))
except: true except CatchableError: true
logging.setupLogLevel(conf.logLevel) logging.setupLogLevel(conf.logLevel)
logging.setupLogFormat(conf.logFormat, color) logging.setupLogFormat(conf.logFormat, color)

View File

@ -451,7 +451,7 @@ proc parseCmdArg*(T: type crypto.PrivateKey, p: string): T =
try: try:
let key = SkPrivateKey.init(utils.fromHex(p)).tryGet() let key = SkPrivateKey.init(utils.fromHex(p)).tryGet()
crypto.PrivateKey(scheme: Secp256k1, skkey: key) crypto.PrivateKey(scheme: Secp256k1, skkey: key)
except: except CatchableError:
raise newException(ConfigurationError, "Invalid private key") raise newException(ConfigurationError, "Invalid private key")
proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] = proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] =
@ -461,7 +461,7 @@ proc completeCmdArg*(T: type crypto.PrivateKey, val: string): seq[string] =
proc parseCmdArg*(T: type ValidIpAddress, p: string): T = proc parseCmdArg*(T: type ValidIpAddress, p: string): T =
try: try:
ValidIpAddress.init(p) ValidIpAddress.init(p)
except: except CatchableError:
raise newException(ConfigurationError, "Invalid IP address") raise newException(ConfigurationError, "Invalid IP address")
proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] = proc completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
@ -476,7 +476,7 @@ proc defaultListenAddress*(): ValidIpAddress =
proc parseCmdArg*(T: type Port, p: string): T = proc parseCmdArg*(T: type Port, p: string): T =
try: try:
Port(parseInt(p)) Port(parseInt(p))
except: except CatchableError:
raise newException(ConfigurationError, "Invalid Port number") raise newException(ConfigurationError, "Invalid Port number")
proc completeCmdArg*(T: type Port, val: string): seq[string] = proc completeCmdArg*(T: type Port, val: string): seq[string] =
@ -485,7 +485,7 @@ proc completeCmdArg*(T: type Port, val: string): seq[string] =
proc parseCmdArg*(T: type Option[int], p: string): T = proc parseCmdArg*(T: type Option[int], p: string): T =
try: try:
some(parseInt(p)) some(parseInt(p))
except: except CatchableError:
raise newException(ConfigurationError, "Invalid number") raise newException(ConfigurationError, "Invalid number")
## Configuration validation ## Configuration validation

View File

@ -608,7 +608,7 @@ when isMainModule:
# Adhere to NO_COLOR initiative: https://no-color.org/ # Adhere to NO_COLOR initiative: https://no-color.org/
let color = try: not parseBool(os.getEnv("NO_COLOR", "false")) let color = try: not parseBool(os.getEnv("NO_COLOR", "false"))
except: true except CatchableError: true
logging.setupLogLevel(conf.logLevel) logging.setupLogLevel(conf.logLevel)
logging.setupLogFormat(conf.logFormat, color) logging.setupLogFormat(conf.logFormat, color)

View File

@ -133,11 +133,11 @@ proc runGanache(): Process =
ganacheStartLog.add(cmdline) ganacheStartLog.add(cmdline)
if cmdline.contains("Listening on 127.0.0.1:8540"): if cmdline.contains("Listening on 127.0.0.1:8540"):
break break
except: except CatchableError:
break break
debug "Ganache daemon is running and ready", pid=ganachePID, startLog=ganacheStartLog debug "Ganache daemon is running and ready", pid=ganachePID, startLog=ganacheStartLog
return runGanache return runGanache
except: except: # TODO: Fix "BareExcept" warning
error "Ganache daemon run failed" error "Ganache daemon run failed"
@ -153,7 +153,7 @@ proc stopGanache(runGanache: Process) {.used.} =
# ref: https://nim-lang.org/docs/osproc.html#waitForExit%2CProcess%2Cint # ref: https://nim-lang.org/docs/osproc.html#waitForExit%2CProcess%2Cint
# debug "ganache logs", logs=runGanache.outputstream.readAll() # debug "ganache logs", logs=runGanache.outputstream.readAll()
debug "Sent SIGTERM to Ganache", ganachePID=ganachePID debug "Sent SIGTERM to Ganache", ganachePID=ganachePID
except: except CatchableError:
error "Ganache daemon termination failed: ", err = getCurrentExceptionMsg() error "Ganache daemon termination failed: ", err = getCurrentExceptionMsg()
proc setup(signer = true): Future[OnchainGroupManager] {.async.} = proc setup(signer = true): Future[OnchainGroupManager] {.async.} =

View File

@ -151,7 +151,7 @@ proc populateInfoFromIp(allPeersRef: CustomPeersTableRef,
await sleepAsync(1400) await sleepAsync(1400)
let response = await restClient.ipToLocation(allPeersRef[peer].ip) let response = await restClient.ipToLocation(allPeersRef[peer].ip)
location = response.data location = response.data
except: except CatchableError:
warn "could not get location", ip=allPeersRef[peer].ip warn "could not get location", ip=allPeersRef[peer].ip
continue continue
allPeersRef[peer].country = location.country allPeersRef[peer].country = location.country
@ -214,7 +214,7 @@ proc getBootstrapFromDiscDns(conf: NetworkMonitorConf): Result[seq[enr.Record],
if tenrRes.isOk() and (tenrRes.get().udp.isSome() or tenrRes.get().udp6.isSome()): if tenrRes.isOk() and (tenrRes.get().udp.isSome() or tenrRes.get().udp6.isSome()):
discv5BootstrapEnrs.add(enr) discv5BootstrapEnrs.add(enr)
return ok(discv5BootstrapEnrs) return ok(discv5BootstrapEnrs)
except: except CatchableError:
error("failed discovering peers from DNS") error("failed discovering peers from DNS")
proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] = proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] =
@ -249,7 +249,7 @@ proc initAndStartNode(conf: NetworkMonitorConf): Result[WakuNode, string] =
node.wakuDiscv5.protocol.open() node.wakuDiscv5.protocol.open()
return ok(node) return ok(node)
except: except CatchableError:
error("could not start node") error("could not start node")
proc startRestApiServer(conf: NetworkMonitorConf, proc startRestApiServer(conf: NetworkMonitorConf,
@ -266,7 +266,7 @@ proc startRestApiServer(conf: NetworkMonitorConf,
var sres = RestServerRef.new(router, serverAddress) var sres = RestServerRef.new(router, serverAddress)
let restServer = sres.get() let restServer = sres.get()
restServer.start() restServer.start()
except: except CatchableError:
error("could not start rest api server") error("could not start rest api server")
ok() ok()

View File

@ -2,7 +2,7 @@ when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].} {.push raises: [Defect].}
else: else:
{.push raises: [].} {.push raises: [].}
import import
std/json, std/json,
stew/results, stew/results,
@ -44,7 +44,7 @@ proc decodeBytes*(t: typedesc[NodeLocation], value: openArray[byte],
long: $jsonContent["lon"].getFloat(), long: $jsonContent["lon"].getFloat(),
isp: jsonContent["isp"].getStr() isp: jsonContent["isp"].getStr()
)) ))
except: except CatchableError:
return err("failed to get the location: " & getCurrentExceptionMsg()) return err("failed to get the location: " & getCurrentExceptionMsg())
proc encodeString*(value: string): RestResult[string] = proc encodeString*(value: string): RestResult[string] =

View File

@ -24,7 +24,7 @@ converter toChroniclesLogLevel(level: LogLevel): chronicles.LogLevel =
## Map logging log levels to the corresponding nim-chronicles' log level ## Map logging log levels to the corresponding nim-chronicles' log level
try: try:
parseEnum[chronicles.LogLevel]($level) parseEnum[chronicles.LogLevel]($level)
except: except CatchableError:
chronicles.LogLevel.NONE chronicles.LogLevel.NONE
@ -71,7 +71,7 @@ proc writeAndFlush(f: File, s: LogOutputStr) =
try: try:
f.write(s) f.write(s)
f.flushFile() f.flushFile()
except: except CatchableError:
logLoggingFailure(cstring(s), getCurrentException()) logLoggingFailure(cstring(s), getCurrentException())

View File

@ -88,7 +88,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var RelayWakuMessage)
# Check for reapeated keys # Check for reapeated keys
if keys.containsOrIncl(fieldName): if keys.containsOrIncl(fieldName):
let err = try: fmt"Multiple `{fieldName}` fields found" let err = try: fmt"Multiple `{fieldName}` fields found"
except: "Multiple fields with the same name found" except CatchableError: "Multiple fields with the same name found"
reader.raiseUnexpectedField(err, "RelayWakuMessage") reader.raiseUnexpectedField(err, "RelayWakuMessage")
case fieldName case fieldName

View File

@ -255,7 +255,7 @@ method getMessages*(
): ArchiveDriverResult[seq[ArchiveRow]] = ): ArchiveDriverResult[seq[ArchiveRow]] =
let cursor = cursor.map(toIndex) let cursor = cursor.map(toIndex)
let matchesQuery: QueryFilterMatcher = proc(row: IndexedWakuMessage): bool = let matchesQuery: QueryFilterMatcher = func(row: IndexedWakuMessage): bool =
if pubsubTopic.isSome() and row.pubsubTopic != pubsubTopic.get(): if pubsubTopic.isSome() and row.pubsubTopic != pubsubTopic.get():
return false return false
@ -273,7 +273,7 @@ method getMessages*(
var pageRes: QueueDriverGetPageResult var pageRes: QueueDriverGetPageResult
try: try:
pageRes = driver.getPage(maxPageSize, ascendingOrder, cursor, matchesQuery) pageRes = driver.getPage(maxPageSize, ascendingOrder, cursor, matchesQuery)
except: except: # TODO: Fix "BareExcept" warning
return err(getCurrentExceptionMsg()) return err(getCurrentExceptionMsg())
if pageRes.isErr(): if pageRes.isErr():

View File

@ -47,7 +47,7 @@ proc clear(m: var SubscriptionManager) =
proc registerSubscription(m: SubscriptionManager, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, handler: FilterPushHandler) = proc registerSubscription(m: SubscriptionManager, pubsubTopic: PubsubTopic, contentTopic: ContentTopic, handler: FilterPushHandler) =
try: try:
m.subscriptions[(pubsubTopic, contentTopic)]= handler m.subscriptions[(pubsubTopic, contentTopic)]= handler
except: except: # TODO: Fix "BareExcept" warning
error "failed to register filter subscription", error=getCurrentExceptionMsg() error "failed to register filter subscription", error=getCurrentExceptionMsg()
proc removeSubscription(m: SubscriptionManager, pubsubTopic: PubsubTopic, contentTopic: ContentTopic) = proc removeSubscription(m: SubscriptionManager, pubsubTopic: PubsubTopic, contentTopic: ContentTopic) =
@ -60,7 +60,7 @@ proc notifySubscriptionHandler(m: SubscriptionManager, pubsubTopic: PubsubTopic,
try: try:
let handler = m.subscriptions[(pubsubTopic, contentTopic)] let handler = m.subscriptions[(pubsubTopic, contentTopic)]
handler(pubsubTopic, message) handler(pubsubTopic, message)
except: except: # TODO: Fix "BareExcept" warning
discard discard
proc getSubscriptionsCount(m: SubscriptionManager): int = proc getSubscriptionsCount(m: SubscriptionManager): int =

View File

@ -3,7 +3,7 @@ when (NimMajor, NimMinor) < (1, 4):
else: else:
{.push raises: [].} {.push raises: [].}
import import
options, json, strutils, options, json, strutils,
std/[algorithm, os, sequtils, sets] std/[algorithm, os, sequtils, sets]
@ -42,7 +42,7 @@ proc createAppKeystore*(path: string,
finally: finally:
f.close() f.close()
# This proc load a keystore based on the application, appIdentifier and version filters. # This proc load a keystore based on the application, appIdentifier and version filters.
# If none is found, it automatically creates an empty keystore for the passed parameters # If none is found, it automatically creates an empty keystore for the passed parameters
proc loadAppKeystore*(path: string, proc loadAppKeystore*(path: string,
appInfo: AppInfo, appInfo: AppInfo,
@ -80,11 +80,11 @@ proc loadAppKeystore*(path: string,
# We parse the json # We parse the json
data = json.parseJson(keystore) data = json.parseJson(keystore)
# We check if parsed json contains the relevant keystore credentials fields and if these are set to the passed parameters # We check if parsed json contains the relevant keystore credentials fields and if these are set to the passed parameters
# (note that "if" is lazy, so if one of the .contains() fails, the json fields contents will not be checked and no ResultDefect will be raised due to accessing unavailable fields) # (note that "if" is lazy, so if one of the .contains() fails, the json fields contents will not be checked and no ResultDefect will be raised due to accessing unavailable fields)
if data.hasKeys(["application", "appIdentifier", "credentials", "version"]) and if data.hasKeys(["application", "appIdentifier", "credentials", "version"]) and
data["application"].getStr() == appInfo.application and data["application"].getStr() == appInfo.application and
data["appIdentifier"].getStr() == appInfo.appIdentifier and data["appIdentifier"].getStr() == appInfo.appIdentifier and
data["version"].getStr() == appInfo.version: data["version"].getStr() == appInfo.version:
# We return the first json keystore that matches the passed app parameters # We return the first json keystore that matches the passed app parameters
# We assume a unique kesytore with such parameters is present in the file # We assume a unique kesytore with such parameters is present in the file
@ -106,7 +106,7 @@ proc loadAppKeystore*(path: string,
return ok(matchingAppKeystore) return ok(matchingAppKeystore)
# Adds a sequence of membership credential to the keystore matching the application, appIdentifier and version filters. # Adds a sequence of membership credential to the keystore matching the application, appIdentifier and version filters.
proc addMembershipCredentials*(path: string, proc addMembershipCredentials*(path: string,
credentials: seq[MembershipCredentials], credentials: seq[MembershipCredentials],
password: string, password: string,
@ -143,7 +143,7 @@ proc addMembershipCredentials*(path: string,
# we parse the json decrypted keystoreCredential # we parse the json decrypted keystoreCredential
let decodedCredentialRes = decode(decodedKeyfileRes.get()) let decodedCredentialRes = decode(decodedKeyfileRes.get())
if decodedCredentialRes.isOk(): if decodedCredentialRes.isOk():
let keyfileMembershipCredential = decodedCredentialRes.get() let keyfileMembershipCredential = decodedCredentialRes.get()
@ -166,13 +166,13 @@ proc addMembershipCredentials*(path: string,
# we update the original credential field in keystoreCredentials # we update the original credential field in keystoreCredentials
keystoreCredential = updatedCredentialKeyfileRes.get() keystoreCredential = updatedCredentialKeyfileRes.get()
found = true found = true
# We stop decrypting other credentials in the keystore # We stop decrypting other credentials in the keystore
break break
# If no credential in keystore with same input identityCredential value is found, we add it # If no credential in keystore with same input identityCredential value is found, we add it
if found == false: if found == false:
let encodedMembershipCredential = membershipCredential.encode() let encodedMembershipCredential = membershipCredential.encode()
@ -183,13 +183,13 @@ proc addMembershipCredentials*(path: string,
# We add it to the credentials field of the keystore # We add it to the credentials field of the keystore
jsonKeystore["credentials"].add(keyfileRes.get()) jsonKeystore["credentials"].add(keyfileRes.get())
except: except CatchableError:
return err(KeystoreJsonError) return err(KeystoreJsonError)
# We save to disk the (updated) keystore. # We save to disk the (updated) keystore.
if save(jsonKeystore, path, separator).isErr(): if save(jsonKeystore, path, separator).isErr():
return err(KeystoreOsError) return err(KeystoreOsError)
return ok() return ok()
# Returns the membership credentials in the keystore matching the application, appIdentifier and version filters, further filtered by the input # Returns the membership credentials in the keystore matching the application, appIdentifier and version filters, further filtered by the input
@ -226,16 +226,16 @@ proc getMembershipCredentials*(path: string,
if decodedKeyfileRes.isOk(): if decodedKeyfileRes.isOk():
# we parse the json decrypted keystoreCredential # we parse the json decrypted keystoreCredential
let decodedCredentialRes = decode(decodedKeyfileRes.get()) let decodedCredentialRes = decode(decodedKeyfileRes.get())
if decodedCredentialRes.isOk(): if decodedCredentialRes.isOk():
let keyfileMembershipCredential = decodedCredentialRes.get() let keyfileMembershipCredential = decodedCredentialRes.get()
let filteredCredentialOpt = filterCredential(keyfileMembershipCredential, filterIdentityCredentials, filterMembershipContracts) let filteredCredentialOpt = filterCredential(keyfileMembershipCredential, filterIdentityCredentials, filterMembershipContracts)
if filteredCredentialOpt.isSome(): if filteredCredentialOpt.isSome():
outputMembershipCredentials.add(filteredCredentialOpt.get()) outputMembershipCredentials.add(filteredCredentialOpt.get())
except: except CatchableError:
return err(KeystoreJsonError) return err(KeystoreJsonError)
return ok(outputMembershipCredentials) return ok(outputMembershipCredentials)

View File

@ -3,7 +3,7 @@ when (NimMajor, NimMinor) < (1, 4):
else: else:
{.push raises: [].} {.push raises: [].}
import import
json, json,
std/[options, os, sequtils], std/[options, os, sequtils],
./keyfile, ./keyfile,
@ -17,17 +17,17 @@ proc hasKeys*(data: JsonNode, keys: openArray[string]): bool =
proc sortMembershipGroup*(a,b: MembershipGroup): int = proc sortMembershipGroup*(a,b: MembershipGroup): int =
return cmp(a.membershipContract.address, b.membershipContract.address) return cmp(a.membershipContract.address, b.membershipContract.address)
# Safely saves a Keystore's JsonNode to disk. # Safely saves a Keystore's JsonNode to disk.
# If exists, the destination file is renamed with extension .bkp; the file is written at its destination and the .bkp file is removed if write is successful, otherwise is restored # If exists, the destination file is renamed with extension .bkp; the file is written at its destination and the .bkp file is removed if write is successful, otherwise is restored
proc save*(json: JsonNode, path: string, separator: string): KeystoreResult[void] = proc save*(json: JsonNode, path: string, separator: string): KeystoreResult[void] =
# We first backup the current keystore # We first backup the current keystore
if fileExists(path): if fileExists(path):
try: try:
moveFile(path, path & ".bkp") moveFile(path, path & ".bkp")
except: except: # TODO: Fix "BareExcept" warning
return err(KeystoreOsError) return err(KeystoreOsError)
# We save the updated json # We save the updated json
var f: File var f: File
if not f.open(path, fmAppend): if not f.open(path, fmAppend):
@ -45,7 +45,7 @@ proc save*(json: JsonNode, path: string, separator: string): KeystoreResult[void
f.close() f.close()
removeFile(path) removeFile(path)
moveFile(path & ".bkp", path) moveFile(path & ".bkp", path)
except: except: # TODO: Fix "BareExcept" warning
# Unlucky, we just fail # Unlucky, we just fail
return err(KeystoreOsError) return err(KeystoreOsError)
return err(KeystoreOsError) return err(KeystoreOsError)
@ -56,7 +56,7 @@ proc save*(json: JsonNode, path: string, separator: string): KeystoreResult[void
if fileExists(path & ".bkp"): if fileExists(path & ".bkp"):
try: try:
removeFile(path & ".bkp") removeFile(path & ".bkp")
except: except CatchableError:
return err(KeystoreOsError) return err(KeystoreOsError)
return ok() return ok()
@ -65,7 +65,7 @@ proc save*(json: JsonNode, path: string, separator: string): KeystoreResult[void
proc filterCredential*(credential: MembershipCredentials, proc filterCredential*(credential: MembershipCredentials,
filterIdentityCredentials: seq[IdentityCredential], filterIdentityCredentials: seq[IdentityCredential],
filterMembershipContracts: seq[MembershipContract]): Option[MembershipCredentials] = filterMembershipContracts: seq[MembershipContract]): Option[MembershipCredentials] =
# We filter by identity credentials # We filter by identity credentials
if filterIdentityCredentials.len() != 0: if filterIdentityCredentials.len() != 0:
if (credential.identityCredential in filterIdentityCredentials) == false: if (credential.identityCredential in filterIdentityCredentials) == false:
@ -74,7 +74,7 @@ proc filterCredential*(credential: MembershipCredentials,
# We filter by membership groups credentials # We filter by membership groups credentials
if filterMembershipContracts.len() != 0: if filterMembershipContracts.len() != 0:
# Here we keep only groups that match a contract in the filter # Here we keep only groups that match a contract in the filter
var membershipGroupsIntersection: seq[MembershipGroup] = @[] var membershipGroupsIntersection: seq[MembershipGroup] = @[]
# We check if we have a group in the input credential matching any contract in the filter # We check if we have a group in the input credential matching any contract in the filter
for membershipGroup in credential.membershipGroups: for membershipGroup in credential.membershipGroups:
if membershipGroup.membershipContract in filterMembershipContracts: if membershipGroup.membershipContract in filterMembershipContracts:
@ -87,9 +87,9 @@ proc filterCredential*(credential: MembershipCredentials,
else: else:
return none(MembershipCredentials) return none(MembershipCredentials)
# We hit this return only if # We hit this return only if
# - filterIdentityCredentials.len() == 0 and filterMembershipContracts.len() == 0 (no filter) # - filterIdentityCredentials.len() == 0 and filterMembershipContracts.len() == 0 (no filter)
# - filterIdentityCredentials.len() != 0 and filterMembershipContracts.len() == 0 (filter only on identity credential) # - filterIdentityCredentials.len() != 0 and filterMembershipContracts.len() == 0 (filter only on identity credential)
# Indeed, filterMembershipContracts.len() != 0 will have its exclusive return based on all values of membershipGroupsIntersection.len() # Indeed, filterMembershipContracts.len() != 0 will have its exclusive return based on all values of membershipGroupsIntersection.len()
return some(credential) return some(credential)

View File

@ -55,7 +55,7 @@ proc getReadingWritingState(hs: HandshakeState, direction: MessageDirection): (b
return (reading, writing) return (reading, writing)
# Checks if a pre-message is valid according to Noise specifications # Checks if a pre-message is valid according to Noise specifications
# http://www.noiseprotocol.org/noise.html#handshake-patterns # http://www.noiseprotocol.org/noise.html#handshake-patterns
proc isValid(msg: seq[PreMessagePattern]): bool = proc isValid(msg: seq[PreMessagePattern]): bool =
@ -86,7 +86,7 @@ proc isValid(msg: seq[PreMessagePattern]): bool =
proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq[NoisePublicKey] = @[]) proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq[NoisePublicKey] = @[])
{.raises: [Defect, NoiseMalformedHandshake, NoiseHandshakeError, NoisePublicKeyError].} = {.raises: [Defect, NoiseMalformedHandshake, NoiseHandshakeError, NoisePublicKeyError].} =
var var
# I make a copy of the input pre-message public keys, so that I can easily delete processed ones without using iterators/counters # I make a copy of the input pre-message public keys, so that I can easily delete processed ones without using iterators/counters
preMessagePKs = inPreMessagePKs preMessagePKs = inPreMessagePKs
# Here we store currently processed pre message public key # Here we store currently processed pre message public key
@ -106,10 +106,10 @@ proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq
let let
direction = messagePattern.direction direction = messagePattern.direction
tokens = messagePattern.tokens tokens = messagePattern.tokens
# We get if the user is reading or writing the current pre-message pattern # We get if the user is reading or writing the current pre-message pattern
var (reading, writing) = getReadingWritingState(hs , direction) var (reading, writing) = getReadingWritingState(hs , direction)
# We process each message pattern token # We process each message pattern token
for token in tokens: for token in tokens:
@ -136,13 +136,13 @@ proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq
else: else:
raise newException(NoisePublicKeyError, "Noise read e, incorrect encryption flag for pre-message public key") raise newException(NoisePublicKeyError, "Noise read e, incorrect encryption flag for pre-message public key")
# If user is writing the "e" token # If user is writing the "e" token
elif writing: elif writing:
trace "noise pre-message write e" trace "noise pre-message write e"
# When writing, the user is sending a public key, # When writing, the user is sending a public key,
# We check that the public part corresponds to the set local key and we call MixHash(e.public_key). # We check that the public part corresponds to the set local key and we call MixHash(e.public_key).
if hs.e.publicKey == intoCurve25519Key(currPK.pk): if hs.e.publicKey == intoCurve25519Key(currPK.pk):
hs.ss.mixHash(hs.e.publicKey) hs.ss.mixHash(hs.e.publicKey)
@ -150,13 +150,13 @@ proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq
raise newException(NoisePublicKeyError, "Noise pre-message e key doesn't correspond to locally set e key pair") raise newException(NoisePublicKeyError, "Noise pre-message e key doesn't correspond to locally set e key pair")
# Noise specification: section 9.2 # Noise specification: section 9.2
# In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results # In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results
# in a call to MixHash(e.public_key). # in a call to MixHash(e.public_key).
# In a PSK handshake, all of these calls are followed by MixKey(e.public_key). # In a PSK handshake, all of these calls are followed by MixKey(e.public_key).
if "psk" in hs.handshakePattern.name: if "psk" in hs.handshakePattern.name:
hs.ss.mixKey(currPK.pk) hs.ss.mixKey(currPK.pk)
# We delete processed public key # We delete processed public key
preMessagePKs.delete(0) preMessagePKs.delete(0)
of T_s: of T_s:
@ -183,10 +183,10 @@ proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq
# If user is writing the "s" token # If user is writing the "s" token
elif writing: elif writing:
trace "noise pre-message write s" trace "noise pre-message write s"
# If writing, it means that the user is sending a public key, # If writing, it means that the user is sending a public key,
# We check that the public part corresponds to the set local key and we call MixHash(s.public_key). # We check that the public part corresponds to the set local key and we call MixHash(s.public_key).
if hs.s.publicKey == intoCurve25519Key(currPK.pk): if hs.s.publicKey == intoCurve25519Key(currPK.pk):
hs.ss.mixHash(hs.s.publicKey) hs.ss.mixHash(hs.s.publicKey)
@ -194,13 +194,13 @@ proc processPreMessagePatternTokens(hs: var HandshakeState, inPreMessagePKs: seq
raise newException(NoisePublicKeyError, "Noise pre-message s key doesn't correspond to locally set s key pair") raise newException(NoisePublicKeyError, "Noise pre-message s key doesn't correspond to locally set s key pair")
# Noise specification: section 9.2 # Noise specification: section 9.2
# In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results # In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results
# in a call to MixHash(e.public_key). # in a call to MixHash(e.public_key).
# In a PSK handshake, all of these calls are followed by MixKey(e.public_key). # In a PSK handshake, all of these calls are followed by MixKey(e.public_key).
if "psk" in hs.handshakePattern.name: if "psk" in hs.handshakePattern.name:
hs.ss.mixKey(currPK.pk) hs.ss.mixKey(currPK.pk)
# We delete processed public key # We delete processed public key
preMessagePKs.delete(0) preMessagePKs.delete(0)
else: else:
@ -239,7 +239,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
messagePattern = hs.handshakePattern.messagePatterns[hs.msgPatternIdx] messagePattern = hs.handshakePattern.messagePatterns[hs.msgPatternIdx]
direction = messagePattern.direction direction = messagePattern.direction
tokens = messagePattern.tokens tokens = messagePattern.tokens
# We get if the user is reading or writing the input handshake message # We get if the user is reading or writing the input handshake message
var (reading, writing) = getReadingWritingState(hs , direction) var (reading, writing) = getReadingWritingState(hs , direction)
@ -256,7 +256,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
# We process each message pattern token # We process each message pattern token
for token in tokens: for token in tokens:
case token case token
of T_e: of T_e:
@ -274,7 +274,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
# Note: by specification, ephemeral keys should always be unencrypted. But we support encrypted ones. # Note: by specification, ephemeral keys should always be unencrypted. But we support encrypted ones.
if currPK.flag == 0.uint8: if currPK.flag == 0.uint8:
# Unencrypted Public Key # Unencrypted Public Key
# Sets re and calls MixHash(re.public_key). # Sets re and calls MixHash(re.public_key).
hs.re = intoCurve25519Key(currPK.pk) hs.re = intoCurve25519Key(currPK.pk)
hs.ss.mixHash(hs.re) hs.ss.mixHash(hs.re)
@ -288,10 +288,10 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
else: else:
raise newException(NoisePublicKeyError, "Noise read e, incorrect encryption flag for public key") raise newException(NoisePublicKeyError, "Noise read e, incorrect encryption flag for public key")
# Noise specification: section 9.2 # Noise specification: section 9.2
# In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results # In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results
# in a call to MixHash(e.public_key). # in a call to MixHash(e.public_key).
# In a PSK handshake, all of these calls are followed by MixKey(e.public_key). # In a PSK handshake, all of these calls are followed by MixKey(e.public_key).
if "psk" in hs.handshakePattern.name: if "psk" in hs.handshakePattern.name:
hs.ss.mixKey(hs.re) hs.ss.mixKey(hs.re)
@ -310,8 +310,8 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
hs.ss.mixHash(hs.e.publicKey) hs.ss.mixHash(hs.e.publicKey)
# Noise specification: section 9.2 # Noise specification: section 9.2
# In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results # In non-PSK handshakes, the "e" token in a pre-message pattern or message pattern always results
# in a call to MixHash(e.public_key). # in a call to MixHash(e.public_key).
# In a PSK handshake, all of these calls are followed by MixKey(e.public_key). # In a PSK handshake, all of these calls are followed by MixKey(e.public_key).
if "psk" in hs.handshakePattern.name: if "psk" in hs.handshakePattern.name:
hs.ss.mixKey(hs.e.publicKey) hs.ss.mixKey(hs.e.publicKey)
@ -334,7 +334,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
# We check if current key is encrypted or not # We check if current key is encrypted or not
if currPK.flag == 0.uint8: if currPK.flag == 0.uint8:
# Unencrypted Public Key # Unencrypted Public Key
# Sets re and calls MixHash(re.public_key). # Sets re and calls MixHash(re.public_key).
hs.rs = intoCurve25519Key(currPK.pk) hs.rs = intoCurve25519Key(currPK.pk)
hs.ss.mixHash(hs.rs) hs.ss.mixHash(hs.rs)
@ -347,7 +347,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
else: else:
raise newException(NoisePublicKeyError, "Noise read s, incorrect encryption flag for public key") raise newException(NoisePublicKeyError, "Noise read s, incorrect encryption flag for public key")
# We delete processed public key # We delete processed public key
inHandshakeMessage.delete(0) inHandshakeMessage.delete(0)
@ -448,7 +448,7 @@ proc processMessagePatternTokens(rng: var rand.HmacDrbgContext, hs: var Handshak
################################# #################################
# Initializes a Handshake State # Initializes a Handshake State
proc initialize*(hsPattern: HandshakePattern, ephemeralKey: KeyPair = default(KeyPair), staticKey: KeyPair = default(KeyPair), prologue: seq[byte] = @[], psk: seq[byte] = @[], preMessagePKs: seq[NoisePublicKey] = @[], initiator: bool = false): HandshakeState proc initialize*(hsPattern: HandshakePattern, ephemeralKey: KeyPair = default(KeyPair), staticKey: KeyPair = default(KeyPair), prologue: seq[byte] = @[], psk: seq[byte] = @[], preMessagePKs: seq[NoisePublicKey] = @[], initiator: bool = false): HandshakeState
{.raises: [Defect, NoiseMalformedHandshake, NoiseHandshakeError, NoisePublicKeyError].} = {.raises: [Defect, NoiseMalformedHandshake, NoiseHandshakeError, NoisePublicKeyError].} =
var hs = HandshakeState.init(hsPattern) var hs = HandshakeState.init(hsPattern)
hs.ss.mixHash(prologue) hs.ss.mixHash(prologue)
@ -470,7 +470,7 @@ proc stepHandshake*(rng: var rand.HmacDrbgContext, hs: var HandshakeState, readP
var hsStepResult: HandshakeStepResult var hsStepResult: HandshakeStepResult
# If there are no more message patterns left for processing # If there are no more message patterns left for processing
# we return an empty HandshakeStepResult # we return an empty HandshakeStepResult
if hs.msgPatternIdx > uint8(hs.handshakePattern.messagePatterns.len - 1): if hs.msgPatternIdx > uint8(hs.handshakePattern.messagePatterns.len - 1):
debug "stepHandshake called more times than the number of message patterns present in handshake" debug "stepHandshake called more times than the number of message patterns present in handshake"
@ -482,12 +482,12 @@ proc stepHandshake*(rng: var rand.HmacDrbgContext, hs: var HandshakeState, readP
let direction = hs.handshakePattern.messagePatterns[hs.msgPatternIdx].direction let direction = hs.handshakePattern.messagePatterns[hs.msgPatternIdx].direction
var (reading, writing) = getReadingWritingState(hs, direction) var (reading, writing) = getReadingWritingState(hs, direction)
# If we write an answer at this handshake step # If we write an answer at this handshake step
if writing: if writing:
# We initialize a payload v2 and we set proper protocol ID (if supported) # We initialize a payload v2 and we set proper protocol ID (if supported)
try: try:
hsStepResult.payload2.protocolId = PayloadV2ProtocolIDs[hs.handshakePattern.name] hsStepResult.payload2.protocolId = PayloadV2ProtocolIDs[hs.handshakePattern.name]
except: except CatchableError:
raise newException(NoiseMalformedHandshake, "Handshake Pattern not supported") raise newException(NoiseMalformedHandshake, "Handshake Pattern not supported")
# We set the messageNametag and the handshake and transport messages # We set the messageNametag and the handshake and transport messages
@ -526,8 +526,8 @@ proc finalizeHandshake*(hs: var HandshakeState): HandshakeResult =
var hsResult: HandshakeResult var hsResult: HandshakeResult
## Noise specification, Section 5: ## Noise specification, Section 5:
## Processing the final handshake message returns two CipherState objects, ## Processing the final handshake message returns two CipherState objects,
## the first for encrypting transport messages from initiator to responder, ## the first for encrypting transport messages from initiator to responder,
## and the second for messages in the other direction. ## and the second for messages in the other direction.
# We call Split() # We call Split()
@ -561,15 +561,15 @@ proc finalizeHandshake*(hs: var HandshakeState): HandshakeResult =
return hsResult return hsResult
################################# #################################
# After-handshake procedures # After-handshake procedures
################################# #################################
## Noise specification, Section 5: ## Noise specification, Section 5:
## Transport messages are then encrypted and decrypted by calling EncryptWithAd() ## Transport messages are then encrypted and decrypted by calling EncryptWithAd()
## and DecryptWithAd() on the relevant CipherState with zero-length associated data. ## and DecryptWithAd() on the relevant CipherState with zero-length associated data.
## If DecryptWithAd() signals an error due to DECRYPT() failure, then the input message is discarded. ## If DecryptWithAd() signals an error due to DECRYPT() failure, then the input message is discarded.
## The application may choose to delete the CipherState and terminate the session on such an error, ## The application may choose to delete the CipherState and terminate the session on such an error,
## or may continue to attempt communications. If EncryptWithAd() or DecryptWithAd() signal an error ## or may continue to attempt communications. If EncryptWithAd() or DecryptWithAd() signal an error
## due to nonce exhaustion, then the application must delete the CipherState and terminate the session. ## due to nonce exhaustion, then the application must delete the CipherState and terminate the session.
# Writes an encrypted message using the proper Cipher State # Writes an encrypted message using the proper Cipher State
@ -604,10 +604,10 @@ proc readMessage*(hsr: var HandshakeResult, readPayload2: PayloadV2, inboundMess
let nametagIsOk = checkNametag(readPayload2.messageNametag, inboundMessageNametagBuffer).isOk let nametagIsOk = checkNametag(readPayload2.messageNametag, inboundMessageNametagBuffer).isOk
assert(nametagIsOk) assert(nametagIsOk)
# At this point the messageNametag matches the expected nametag. # At this point the messageNametag matches the expected nametag.
# According to 35/WAKU2-NOISE RFC, no Handshake protocol information is sent when exchanging messages # According to 35/WAKU2-NOISE RFC, no Handshake protocol information is sent when exchanging messages
if readPayload2.protocolId == 0.uint8: if readPayload2.protocolId == 0.uint8:
# On application level we decide to discard messages which fail decryption, without raising an error # On application level we decide to discard messages which fail decryption, without raising an error
try: try:
# Decryption is done with messageNametag as associated data # Decryption is done with messageNametag as associated data
@ -620,4 +620,4 @@ proc readMessage*(hsr: var HandshakeResult, readPayload2: PayloadV2, inboundMess
debug "A read message failed decryption. Returning empty message as plaintext." debug "A read message failed decryption. Returning empty message as plaintext."
message = @[] message = @[]
return ok(message) return ok(message)

View File

@ -37,11 +37,11 @@ proc randomSeqByte*(rng: var HmacDrbgContext, size: int): seq[byte] =
# Pads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3 # Pads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
proc pkcs7_pad*(payload: seq[byte], paddingSize: int): seq[byte] = proc pkcs7_pad*(payload: seq[byte], paddingSize: int): seq[byte] =
assert(paddingSize<256) assert(paddingSize<256)
let k = paddingSize - (payload.len mod paddingSize) let k = paddingSize - (payload.len mod paddingSize)
var padding: seq[byte] var padding: seq[byte]
if k != 0: if k != 0:
@ -94,13 +94,13 @@ proc fromQr*(qr: string): (string, string, string, EllipticCurveKey, MDigest[256
let applicationVersion: string = decode(values[1]) let applicationVersion: string = decode(values[1])
let shardId: string = decode(values[2]) let shardId: string = decode(values[2])
let decodedEphemeralKey = decode(values[3]).toBytes let decodedEphemeralKey = decode(values[3]).toBytes
var ephemeralKey: EllipticCurveKey var ephemeralKey: EllipticCurveKey
for i in 0..<ephemeralKey.len: for i in 0..<ephemeralKey.len:
ephemeralKey[i] = decodedEphemeralKey[i] ephemeralKey[i] = decodedEphemeralKey[i]
let committedStaticKey = seqToDigest256(decode(values[4]).toBytes) let committedStaticKey = seqToDigest256(decode(values[4]).toBytes)
return (applicationName, applicationVersion, shardId, ephemeralKey, committedStaticKey) return (applicationName, applicationVersion, shardId, ephemeralKey, committedStaticKey)
# Converts a sequence or array (arbitrary size) to a MessageNametag # Converts a sequence or array (arbitrary size) to a MessageNametag
@ -109,12 +109,12 @@ proc toMessageNametag*(input: openArray[byte]): MessageNametag =
# We set its length to the default message nametag length (will be truncated or 0-padded) # We set its length to the default message nametag length (will be truncated or 0-padded)
byte_seq.setLen(MessageNametagLength) byte_seq.setLen(MessageNametagLength)
# We copy it to a MessageNametag # We copy it to a MessageNametag
var messageNametag: MessageNametag var messageNametag: MessageNametag
for i in 0..<MessageNametagLength: for i in 0..<MessageNametagLength:
messageNametag[i] = byte_seq[i] messageNametag[i] = byte_seq[i]
return messageNametag return messageNametag
# Uses the cryptographic information stored in the input handshake state to generate a random message nametag # Uses the cryptographic information stored in the input handshake state to generate a random message nametag
@ -129,9 +129,9 @@ proc genMessageNametagSecrets*(hs: HandshakeState): (array[MessageNametagSecretL
sha256.hkdf(hs.ss.h.data, [], [], output) sha256.hkdf(hs.ss.h.data, [], [], output)
return (output[0], output[1]) return (output[0], output[1])
# Simple utility that checks if the given variable is "default", # Simple utility that checks if the given variable is "default",
# Therefore, it has not been initialized # Therefore, it has not been initialized
proc isDefault*[T](value: T): bool = proc isDefault*[T](value: T): bool =
value == static(default(T)) value == static(default(T))
################################################################# #################################################################
@ -156,7 +156,7 @@ proc getPublicKey*(keypair: KeyPair): EllipticCurveKey =
return keypair.publicKey return keypair.publicKey
# Prints Handshake Patterns using Noise pattern layout # Prints Handshake Patterns using Noise pattern layout
proc print*(self: HandshakePattern) proc print*(self: HandshakePattern)
{.raises: [IOError, NoiseMalformedHandshake].}= {.raises: [IOError, NoiseMalformedHandshake].}=
try: try:
if self.name != "": if self.name != "":
@ -170,10 +170,10 @@ proc print*(self: HandshakePattern)
for token in pattern.tokens: for token in pattern.tokens:
if first: if first:
stdout.write " ", token stdout.write " ", token
first = false first = false
else: else:
stdout.write ", ", token stdout.write ", ", token
stdout.write "\n" stdout.write "\n"
stdout.flushFile() stdout.flushFile()
stdout.write " ...\n" stdout.write " ...\n"
stdout.flushFile() stdout.flushFile()
@ -184,12 +184,12 @@ proc print*(self: HandshakePattern)
for token in pattern.tokens: for token in pattern.tokens:
if first: if first:
stdout.write " ", token stdout.write " ", token
first = false first = false
else: else:
stdout.write ", ", token stdout.write ", ", token
stdout.write "\n" stdout.write "\n"
stdout.flushFile() stdout.flushFile()
except: except CatchableError:
raise newException(NoiseMalformedHandshake, "HandshakePattern malformed") raise newException(NoiseMalformedHandshake, "HandshakePattern malformed")
# Hashes a Noise protocol name using SHA256 # Hashes a Noise protocol name using SHA256
@ -198,7 +198,7 @@ proc hashProtocol*(protocolName: string): MDigest[256] =
# The output hash value # The output hash value
var hash: MDigest[256] var hash: MDigest[256]
# From Noise specification: Section 5.2 # From Noise specification: Section 5.2
# http://www.noiseprotocol.org/noise.html#the-symmetricstate-object # http://www.noiseprotocol.org/noise.html#the-symmetricstate-object
# If protocol_name is less than or equal to HASHLEN bytes in length, # If protocol_name is less than or equal to HASHLEN bytes in length,
# sets h equal to protocol_name with zero bytes appended to make HASHLEN bytes. # sets h equal to protocol_name with zero bytes appended to make HASHLEN bytes.
@ -232,12 +232,12 @@ proc genAuthcode*(hs: HandshakeState): string =
# Initializes the empty Message nametag buffer. The n-th nametag is equal to HKDF( secret || n ) # Initializes the empty Message nametag buffer. The n-th nametag is equal to HKDF( secret || n )
proc initNametagsBuffer*(mntb: var MessageNametagBuffer) = proc initNametagsBuffer*(mntb: var MessageNametagBuffer) =
# We default the counter and buffer fields # We default the counter and buffer fields
mntb.counter = 0 mntb.counter = 0
mntb.buffer = default(array[MessageNametagBufferSize, MessageNametag]) mntb.buffer = default(array[MessageNametagBufferSize, MessageNametag])
if mntb.secret.isSome: if mntb.secret.isSome:
for i in 0..<mntb.buffer.len: for i in 0..<mntb.buffer.len:
mntb.buffer[i] = toMessageNametag(sha256.digest(@(mntb.secret.get()) & @(toBytesLE(mntb.counter))).data) mntb.buffer[i] = toMessageNametag(sha256.digest(@(mntb.secret.get()) & @(toBytesLE(mntb.counter))).data)
mntb.counter += 1 mntb.counter += 1
@ -258,7 +258,7 @@ proc delete*(mntb: var MessageNametagBuffer, n: int) =
# Note that if the input MessageNametagBuffer is set to default, nothing is done here # Note that if the input MessageNametagBuffer is set to default, nothing is done here
if mntb.secret.isSome: if mntb.secret.isSome:
# We rotate left the array by n # We rotate left the array by n
mntb.buffer.rotateLeft(n) mntb.buffer.rotateLeft(n)
for i in 0..<n: for i in 0..<n:
@ -271,9 +271,9 @@ proc delete*(mntb: var MessageNametagBuffer, n: int) =
# Checks if the input messageNametag is contained in the input MessageNametagBuffer # Checks if the input messageNametag is contained in the input MessageNametagBuffer
proc checkNametag*(messageNametag: MessageNametag, mntb: var MessageNametagBuffer): Result[bool, cstring] proc checkNametag*(messageNametag: MessageNametag, mntb: var MessageNametagBuffer): Result[bool, cstring]
{.raises: [Defect, NoiseMessageNametagError, NoiseSomeMessagesWereLost].} = {.raises: [Defect, NoiseMessageNametagError, NoiseSomeMessagesWereLost].} =
let index = mntb.buffer.find(messageNametag) let index = mntb.buffer.find(messageNametag)
if index == -1: if index == -1:
@ -297,7 +297,7 @@ proc dh*(private: EllipticCurveKey, public: EllipticCurveKey): EllipticCurveKey
# The output result of the Diffie-Hellman operation # The output result of the Diffie-Hellman operation
var output: EllipticCurveKey var output: EllipticCurveKey
# Since the EC multiplication writes the result to the input, we copy the input to the output variable # Since the EC multiplication writes the result to the input, we copy the input to the output variable
output = public output = public
# We execute the DH operation # We execute the DH operation
EllipticCurve.mul(output, private) EllipticCurve.mul(output, private)
@ -334,7 +334,7 @@ proc randomChaChaPolyCipherState*(rng: var HmacDrbgContext): ChaChaPolyCipherSta
# Checks equality between two Noise public keys # Checks equality between two Noise public keys
proc `==`*(k1, k2: NoisePublicKey): bool = proc `==`*(k1, k2: NoisePublicKey): bool =
return (k1.flag == k2.flag) and (k1.pk == k2.pk) return (k1.flag == k2.flag) and (k1.pk == k2.pk)
# Converts a public Elliptic Curve key to an unencrypted Noise public key # Converts a public Elliptic Curve key to an unencrypted Noise public key
proc toNoisePublicKey*(publicKey: EllipticCurveKey): NoisePublicKey = proc toNoisePublicKey*(publicKey: EllipticCurveKey): NoisePublicKey =
var noisePublicKey: NoisePublicKey var noisePublicKey: NoisePublicKey
@ -353,13 +353,13 @@ proc genNoisePublicKey*(rng: var HmacDrbgContext): NoisePublicKey =
noisePublicKey.pk = getBytes(keyPair.publicKey) noisePublicKey.pk = getBytes(keyPair.publicKey)
return noisePublicKey return noisePublicKey
# Converts a Noise public key to a stream of bytes as in # Converts a Noise public key to a stream of bytes as in
# https://rfc.vac.dev/spec/35/#public-keys-serialization # https://rfc.vac.dev/spec/35/#public-keys-serialization
proc serializeNoisePublicKey*(noisePublicKey: NoisePublicKey): seq[byte] = proc serializeNoisePublicKey*(noisePublicKey: NoisePublicKey): seq[byte] =
var serializedNoisePublicKey: seq[byte] var serializedNoisePublicKey: seq[byte]
# Public key is serialized as (flag || pk) # Public key is serialized as (flag || pk)
# Note that pk contains the X coordinate of the public key if unencrypted # Note that pk contains the X coordinate of the public key if unencrypted
# or the encryption concatenated with the authorization tag if encrypted # or the encryption concatenated with the authorization tag if encrypted
serializedNoisePublicKey.add noisePublicKey.flag serializedNoisePublicKey.add noisePublicKey.flag
serializedNoisePublicKey.add noisePublicKey.pk serializedNoisePublicKey.add noisePublicKey.pk
return serializedNoisePublicKey return serializedNoisePublicKey
@ -382,8 +382,8 @@ proc intoNoisePublicKey*(serializedNoisePublicKey: seq[byte]): NoisePublicKey
proc encryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePublicKey): NoisePublicKey proc encryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePublicKey): NoisePublicKey
{.raises: [Defect, NoiseEmptyChaChaPolyInput, NoiseNonceMaxError].} = {.raises: [Defect, NoiseEmptyChaChaPolyInput, NoiseNonceMaxError].} =
var encryptedNoisePublicKey: NoisePublicKey var encryptedNoisePublicKey: NoisePublicKey
# We proceed with encryption only if # We proceed with encryption only if
# - a key is set in the cipher state # - a key is set in the cipher state
# - the public key is unencrypted # - the public key is unencrypted
if cs.k != EmptyKey and noisePublicKey.flag == 0: if cs.k != EmptyKey and noisePublicKey.flag == 0:
let encPk = encrypt(cs, noisePublicKey.pk) let encPk = encrypt(cs, noisePublicKey.pk)
@ -401,8 +401,8 @@ proc encryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePubl
proc decryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePublicKey): NoisePublicKey proc decryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePublicKey): NoisePublicKey
{.raises: [Defect, NoiseEmptyChaChaPolyInput, NoiseDecryptTagError].} = {.raises: [Defect, NoiseEmptyChaChaPolyInput, NoiseDecryptTagError].} =
var decryptedNoisePublicKey: NoisePublicKey var decryptedNoisePublicKey: NoisePublicKey
# We proceed with decryption only if # We proceed with decryption only if
# - a key is set in the cipher state # - a key is set in the cipher state
# - the public key is encrypted # - the public key is encrypted
if cs.k != EmptyKey and noisePublicKey.flag == 1: if cs.k != EmptyKey and noisePublicKey.flag == 1:
# Since the pk field would contain an encryption + tag, we retrieve the ciphertext length # Since the pk field would contain an encryption + tag, we retrieve the ciphertext length
@ -411,7 +411,7 @@ proc decryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePubl
let pk = noisePublicKey.pk[0..<pkLen] let pk = noisePublicKey.pk[0..<pkLen]
let pkAuth = intoChaChaPolyTag(noisePublicKey.pk[pkLen..<pkLen+ChaChaPolyTag.len]) let pkAuth = intoChaChaPolyTag(noisePublicKey.pk[pkLen..<pkLen+ChaChaPolyTag.len])
# We convert it to a ChaChaPolyCiphertext # We convert it to a ChaChaPolyCiphertext
let ciphertext = ChaChaPolyCiphertext(data: pk, tag: pkAuth) let ciphertext = ChaChaPolyCiphertext(data: pk, tag: pkAuth)
# We run decryption and store its value to a non-encrypted Noise public key (flag = 0) # We run decryption and store its value to a non-encrypted Noise public key (flag = 0)
decryptedNoisePublicKey.pk = decrypt(cs, ciphertext) decryptedNoisePublicKey.pk = decrypt(cs, ciphertext)
decryptedNoisePublicKey.flag = 0 decryptedNoisePublicKey.flag = 0
@ -428,11 +428,11 @@ proc decryptNoisePublicKey*(cs: ChaChaPolyCipherState, noisePublicKey: NoisePubl
# Checks equality between two PayloadsV2 objects # Checks equality between two PayloadsV2 objects
proc `==`*(p1, p2: PayloadV2): bool = proc `==`*(p1, p2: PayloadV2): bool =
return (p1.messageNametag == p2.messageNametag) and return (p1.messageNametag == p2.messageNametag) and
(p1.protocolId == p2.protocolId) and (p1.protocolId == p2.protocolId) and
(p1.handshakeMessage == p2.handshakeMessage) and (p1.handshakeMessage == p2.handshakeMessage) and
(p1.transportMessage == p2.transportMessage) (p1.transportMessage == p2.transportMessage)
# Generates a random PayloadV2 # Generates a random PayloadV2
proc randomPayloadV2*(rng: var HmacDrbgContext): PayloadV2 = proc randomPayloadV2*(rng: var HmacDrbgContext): PayloadV2 =
@ -458,7 +458,7 @@ proc serializePayloadV2*(self: PayloadV2): Result[seq[byte], cstring] =
# We collect public keys contained in the handshake message # We collect public keys contained in the handshake message
var var
# According to https://rfc.vac.dev/spec/35/, the maximum size for the handshake message is 256 bytes, that is # According to https://rfc.vac.dev/spec/35/, the maximum size for the handshake message is 256 bytes, that is
# the handshake message length can be represented with 1 byte only. (its length can be stored in 1 byte) # the handshake message length can be represented with 1 byte only. (its length can be stored in 1 byte)
# However, to ease public keys length addition operation, we declare it as int and later cast to uit8 # However, to ease public keys length addition operation, we declare it as int and later cast to uit8
serializedHandshakeMessageLen: int = 0 serializedHandshakeMessageLen: int = 0
@ -472,7 +472,7 @@ proc serializePayloadV2*(self: PayloadV2): Result[seq[byte], cstring] =
serializedPk = serializeNoisePublicKey(pk) serializedPk = serializeNoisePublicKey(pk)
# We sum its serialized length to the total # We sum its serialized length to the total
serializedHandshakeMessageLen += serializedPk.len serializedHandshakeMessageLen += serializedPk.len
# We add its serialization to the concatenation of all serialized public keys in the handshake message # We add its serialization to the concatenation of all serialized public keys in the handshake message
serializedHandshakeMessage.add serializedPk serializedHandshakeMessage.add serializedPk
# If we are processing more than 256 byte, we return an error # If we are processing more than 256 byte, we return an error
if serializedHandshakeMessageLen > uint8.high.int: if serializedHandshakeMessageLen > uint8.high.int:
@ -482,17 +482,17 @@ proc serializePayloadV2*(self: PayloadV2): Result[seq[byte], cstring] =
# We get the transport message byte length # We get the transport message byte length
let transportMessageLen = self.transportMessage.len let transportMessageLen = self.transportMessage.len
# The output payload as in https://rfc.vac.dev/spec/35/. We concatenate all the PayloadV2 fields as # The output payload as in https://rfc.vac.dev/spec/35/. We concatenate all the PayloadV2 fields as
# payload = ( protocolId || serializedHandshakeMessageLen || serializedHandshakeMessage || transportMessageLen || transportMessage) # payload = ( protocolId || serializedHandshakeMessageLen || serializedHandshakeMessage || transportMessageLen || transportMessage)
# We declare it as a byte sequence of length accordingly to the PayloadV2 information read # We declare it as a byte sequence of length accordingly to the PayloadV2 information read
var payload = newSeqOfCap[byte](MessageNametagLength + #MessageNametagLength bytes for messageNametag var payload = newSeqOfCap[byte](MessageNametagLength + #MessageNametagLength bytes for messageNametag
1 + # 1 byte for protocol ID 1 + # 1 byte for protocol ID
1 + # 1 byte for length of serializedHandshakeMessage field 1 + # 1 byte for length of serializedHandshakeMessage field
serializedHandshakeMessageLen + # serializedHandshakeMessageLen bytes for serializedHandshakeMessage serializedHandshakeMessageLen + # serializedHandshakeMessageLen bytes for serializedHandshakeMessage
8 + # 8 bytes for transportMessageLen 8 + # 8 bytes for transportMessageLen
transportMessageLen # transportMessageLen bytes for transportMessage transportMessageLen # transportMessageLen bytes for transportMessage
) )
# We concatenate all the data # We concatenate all the data
# The protocol ID (1 byte) and handshake message length (1 byte) can be directly casted to byte to allow direct copy to the payload byte sequence # The protocol ID (1 byte) and handshake message length (1 byte) can be directly casted to byte to allow direct copy to the payload byte sequence
payload.add @(self.messageNametag) payload.add @(self.messageNametag)
@ -571,7 +571,7 @@ proc deserializePayloadV2*(payload: seq[byte]): Result[PayloadV2, cstring]
let transportMessageLen = fromBytesLE(uint64, payload[i..(i+8-1)]) let transportMessageLen = fromBytesLE(uint64, payload[i..(i+8-1)])
i += 8 i += 8
# We read the transport message (handshakeMessage bytes) # We read the transport message (handshakeMessage bytes)
payload2.transportMessage = payload[i..i+transportMessageLen-1] payload2.transportMessage = payload[i..i+transportMessageLen-1]
i += transportMessageLen i += transportMessageLen

View File

@ -175,7 +175,7 @@ proc parseEvent*(event: type MemberRegistered,
# Parse the index # Parse the index
offset += decode(data, offset, index) offset += decode(data, offset, index)
return ok(Membership(idCommitment: idComm.toIDCommitment(), index: index.toMembershipIndex())) return ok(Membership(idCommitment: idComm.toIDCommitment(), index: index.toMembershipIndex()))
except: except CatchableError:
return err("failed to parse the data field of the MemberRegistered event") return err("failed to parse the data field of the MemberRegistered event")
type BlockTable* = OrderedTable[BlockNumber, seq[Membership]] type BlockTable* = OrderedTable[BlockNumber, seq[Membership]]
@ -298,7 +298,7 @@ proc startListeningToEvents*(g: OnchainGroupManager): Future[void] {.async.} =
let newHeadCallback = g.getNewHeadCallback() let newHeadCallback = g.getNewHeadCallback()
try: try:
discard await ethRpc.subscribeForBlockHeaders(newHeadCallback, newHeadErrCallback) discard await ethRpc.subscribeForBlockHeaders(newHeadCallback, newHeadErrCallback)
except: except CatchableError:
raise newException(ValueError, "failed to subscribe to block headers: " & getCurrentExceptionMsg()) raise newException(ValueError, "failed to subscribe to block headers: " & getCurrentExceptionMsg())
proc startOnchainSync*(g: OnchainGroupManager, fromBlock: BlockNumber = BlockNumber(0)): Future[void] {.async.} = proc startOnchainSync*(g: OnchainGroupManager, fromBlock: BlockNumber = BlockNumber(0)): Future[void] {.async.} =
@ -306,13 +306,13 @@ proc startOnchainSync*(g: OnchainGroupManager, fromBlock: BlockNumber = BlockNum
try: try:
await g.getEventsAndSeedIntoTree(fromBlock, some(fromBlock)) await g.getEventsAndSeedIntoTree(fromBlock, some(fromBlock))
except: except CatchableError:
raise newException(ValueError, "failed to get the history/reconcile missed blocks: " & getCurrentExceptionMsg()) raise newException(ValueError, "failed to get the history/reconcile missed blocks: " & getCurrentExceptionMsg())
# listen to blockheaders and contract events # listen to blockheaders and contract events
try: try:
await g.startListeningToEvents() await g.startListeningToEvents()
except: except CatchableError:
raise newException(ValueError, "failed to start listening to events: " & getCurrentExceptionMsg()) raise newException(ValueError, "failed to start listening to events: " & getCurrentExceptionMsg())
proc persistCredentials*(g: OnchainGroupManager): GroupManagerResult[void] = proc persistCredentials*(g: OnchainGroupManager): GroupManagerResult[void] =
@ -358,7 +358,7 @@ method startGroupSync*(g: OnchainGroupManager): Future[void] {.async.} =
# Get archive history # Get archive history
try: try:
await startOnchainSync(g) await startOnchainSync(g)
except: except CatchableError:
raise newException(ValueError, "failed to start onchain sync service: " & getCurrentExceptionMsg()) raise newException(ValueError, "failed to start onchain sync service: " & getCurrentExceptionMsg())
if g.ethPrivateKey.isSome() and g.idCredentials.isNone(): if g.ethPrivateKey.isSome() and g.idCredentials.isNone():
@ -393,7 +393,7 @@ method init*(g: OnchainGroupManager): Future[void] {.async.} =
# check if the Ethereum client is reachable # check if the Ethereum client is reachable
try: try:
ethRpc = await newWeb3(g.ethClientUrl) ethRpc = await newWeb3(g.ethClientUrl)
except: except CatchableError:
raise newException(ValueError, "could not connect to the Ethereum client") raise newException(ValueError, "could not connect to the Ethereum client")
# Set the chain id # Set the chain id
@ -416,7 +416,7 @@ method init*(g: OnchainGroupManager): Future[void] {.async.} =
var membershipFee: Uint256 var membershipFee: Uint256
try: try:
membershipFee = await contract.MEMBERSHIP_DEPOSIT().call() membershipFee = await contract.MEMBERSHIP_DEPOSIT().call()
except: except CatchableError:
raise newException(ValueError, "could not get the membership deposit") raise newException(ValueError, "could not get the membership deposit")
@ -445,7 +445,7 @@ method init*(g: OnchainGroupManager): Future[void] {.async.} =
info "reconnecting with the Ethereum client, and restarting group sync", fromBlock = fromBlock info "reconnecting with the Ethereum client, and restarting group sync", fromBlock = fromBlock
try: try:
asyncSpawn g.startOnchainSync(fromBlock) asyncSpawn g.startOnchainSync(fromBlock)
except: except CatchableError:
error "failed to restart group sync", error = getCurrentExceptionMsg() error "failed to restart group sync", error = getCurrentExceptionMsg()
g.initialized = true g.initialized = true