Skip to content

Commit

Permalink
feat(credentials): check presence of idCredential in keystore and add…
Browse files Browse the repository at this point in the history
… only new membership groups
  • Loading branch information
s1fr0 committed Jan 23, 2023
1 parent bb9d869 commit cc75811
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 19 deletions.
52 changes: 50 additions & 2 deletions tests/v2/test_utils_credentials.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ procSuite "Credentials test suite":
check:
keystore.isOk()
]#

asyncTest "Load keystore":
Expand Down Expand Up @@ -97,5 +96,54 @@ procSuite "Credentials test suite":
appIdentifier = "1234",
version = "0.1")
check:
keystore.isOk()
]#

asyncTest "Find credential in keystore":

let filepath = "./testAppKeystore.txt"
#defer: removeFile(filepath)

# We generate a random identity credential (inter-value constrains are not enforced, otherwise we need to load e.g. zerokit RLN keygen)
var
idTrapdoor = randomSeqByte(rng[], 32)
idNullifier = randomSeqByte(rng[], 32)
idSecretHash = randomSeqByte(rng[], 32)
idCommitment = randomSeqByte(rng[], 32)

var idCredential = IdentityCredential(idTrapdoor: idTrapdoor, idNullifier: idNullifier, idSecretHash: idSecretHash, idCommitment: idCommitment)

debug "the generated identity credential: ", idCredential

var index = MembershipIndex(1)

# We generate two membership credentials with same identity credential
let rlnMembershipCredentials1 = MembershipCredentials(identityCredential: idCredential,
membershipGroups: @[MembershipGroup(chainId: "5",
contract: "0x0123456789012345678901234567890123456789",
treeIndex: index) ])

let rlnMembershipCredentials2 = MembershipCredentials(identityCredential: idCredential,
membershipGroups: @[MembershipGroup(chainId: "6",
contract: "0x0000000000000000000000000000000000000000",
treeIndex: index) ])

# This is the same as rlnMembershipCredentials2, should not change the keystore entry of idCredential
let rlnMembershipCredentials3 = MembershipCredentials(identityCredential: idCredential,
membershipGroups: @[MembershipGroup(chainId: "6",
contract: "0x0000000000000000000000000000000000000000",
treeIndex: index) ])

let password = "%m0um0ucoW%"

let keystore = addMembershipCredentials(path = filepath,
credentials = @[rlnMembershipCredentials1, rlnMembershipCredentials2, rlnMembershipCredentials3],
password = password,
application = "test",
appIdentifier = "1234",
version = "0.1")

check:
keystore.isOk()
67 changes: 50 additions & 17 deletions waku/v2/utils/credentials.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ else:
import
chronicles, options, json, strutils,
stew/byteutils,
std/os,
std/[os, sequtils, sets],
./keyfile

type
Expand Down Expand Up @@ -71,24 +71,66 @@ proc toString(credential: MembershipCredentials): string =
proc contains(keystore: var JsonNode, password: string, membershipCredential: MembershipCredentials): KeystoreResult[void] =

try:
var credentials = keystore["credentials"]
for credential in credentials.mitems():
# We get all credentials in keystore
var keystoreCredentials = keystore["credentials"]
for credential in keystoreCredentials.mitems():
echo "credential at origin ", credential
# credential is encrypted. We decrypt it
let decodedKeyfile = decodeKeyFileJson(credential, password)
if decodedKeyfile.isOk():
try:
# we parse the json decrypted credential
let jsonObject = parseJson(string.fromBytes(decodedKeyfile.get()))
let keyfileMembershipCredential = to(jsonObject, MembershipCredentials)

# We check if the decrypted credential has its identityCredential field equal to the input credential
if keyfileMembershipCredential.identityCredential == membershipCredential.identityCredential:
echo "found!"
# idCredential is present in keystore. We add the input credential membership group to the one contained in the decrypted keystore credential (we deduplicate groups using sets)
let allMemberships = toSeq(toHashSet(keyfileMembershipCredential.membershipGroups) + toHashSet(membershipCredential.membershipGroups))

# we define the updated credential with the updated membership sets
let updatedCredential = MembershipCredentials(identityCredential: keyfileMembershipCredential.identityCredential, membershipGroups: allMemberships)

# we re-encrypt creating a new keyfile
let updatedCredentialString = updatedCredential.toString()
let updatedKeyfile = createKeyFileJson(toBytes(updatedCredentialString), password)
if updatedKeyfile.isErr():
return err(CreateKeyfileError)

# we update the original credential field in keystoreCredentials
credential = updatedKeyfile.get()

echo "updkeyfile ", updatedKeyfile
echo "credential ", credential
return ok()

# TODO: we might continue rather than return for some of these errors
except JsonParsingError:
return err(JsonError)
except OSError:
return err(OsError)
except Exception: #parseJson raises Exception
return err(OsError)
return ok()

# no credential in keystore with same input identityCredential value found. We add it
# ...

try:
let membershipCredentialString = membershipCredential.toString()
let keyfile = createKeyFileJson(toBytes(membershipCredentialString), password)
if keyfile.isErr():
return err(CreateKeyfileError)

keystore["credentials"].add(keyfile.get())
echo "newly added ", keystore


#TODO: save to disk the updated keystore
return ok()

except KeyError:
return err(JsonKeyError)

except:
return err(JsonError)

Expand Down Expand Up @@ -203,21 +245,12 @@ proc addMembershipCredentials*(path: string,
var jsonKeystore = jsonKeystoreOpt.get()

for credential in credentials:
let credentialString = credential.toString()
let keyfile = createKeyFileJson(toBytes(credentialString), password)
if keyfile.isErr():
return err(CreateKeyfileError)

# we add the keyfile encrypting the credential to the credentials field
# note that credentials exists as field otherwise loadAppKeystore would fail.
try:
# TEST
if contains(keystore = jsonKeystore, password = password, membershipCredential = keyfile.get()).isOk():
echo "is ok"
jsonKeystore["credentials"].add(keyfile.get())
echo jsonKeystore
except KeyError:
return err(JsonKeyError)
if contains(keystore = jsonKeystore, password = password, membershipCredential = credential).isOk():
echo "is ok"


return ok()

Expand Down

0 comments on commit cc75811

Please sign in to comment.