Skip to content

Commit

Permalink
Merge pull request #349 from hypersign-protocol/348-duplicate-publick…
Browse files Browse the repository at this point in the history
…eymultibase-error

fix: added temporary validation for `EcdsaSecp256k1VerificationKey2019` VM type to allow duplicate `publicKeyMultibase` only when `blockchainAccountId`s are provided
  • Loading branch information
arnabghose997 committed Mar 22, 2023
2 parents 7031fa2 + 348d56b commit 0369721
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 14 deletions.
170 changes: 166 additions & 4 deletions tests/e2e/ssi_tests/e2e_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ def create_did_test():
create_tx_cmd = form_did_create_tx_multisig(did_doc_string, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering DID by passing both Alice's and Eve's Signature")

print("8. FAIL: Alice tries to register a DID Document with duplicate publicKeyMultibase of type Ed25519VerificationKey2020 \n")
kp_alice = generate_key_pair()
signers = []
did_doc_string = generate_did_document(kp_alice)
did_doc_string_2 = generate_did_document(kp_alice)

did_doc_string_vm_1 = did_doc_string["verificationMethod"][0]
did_doc_string_vm_2 = did_doc_string_2["verificationMethod"][0]
did_doc_string_vm_2["id"] = did_doc_string_vm_2["id"] + "new"

did_doc_string["verificationMethod"] = [
did_doc_string_vm_1,
did_doc_string_vm_2
]

did_doc_alice = did_doc_string["id"]
signPair_alice = {
"kp": kp_alice,
"verificationMethodId": did_doc_string["verificationMethod"][0]["id"],
"signing_algo": "ed25519"
}
signers.append(signPair_alice)
create_tx_cmd = form_did_create_tx_multisig(did_doc_string, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering Alice's DID with Id: {did_doc_alice}", True, True)

print("--- Test Completed ---\n")

# TC - II : Update DID scenarios
Expand Down Expand Up @@ -730,7 +755,7 @@ def caip10_cosmos_support_test():
"cosmos:::::23",
"cosmos::0x1234567"
]

print("1. FAIL: Registering a DID Document with an invalid blockchainAccountIds.\n")
for invalid_blockchain_id in invalid_blockchain_account_ids:
print("Registering a DID Document with an invalid blockchainAccountId:", invalid_blockchain_id)
kp = generate_key_pair(algo=kp_algo)
Expand All @@ -749,7 +774,7 @@ def caip10_cosmos_support_test():
create_tx_cmd = form_did_create_tx_multisig(did_doc_string, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering a DID Document with an invalid blockchainAccountId: {invalid_blockchain_id}", True, True)

print("Registering a DID with a VM of type EcdsaSecp256k1VerificationKey2019 having both publicKeyMultibase and blockchainAccountId attributes populated")
print("2. PASS: Registering a DID with a VM of type EcdsaSecp256k1VerificationKey2019 having both publicKeyMultibase and blockchainAccountId attributes populated")
kp = generate_key_pair(algo=kp_algo)
did_doc_string = generate_did_document(kp, kp_algo)
did_doc_id = did_doc_string["id"]
Expand All @@ -763,7 +788,7 @@ def caip10_cosmos_support_test():
create_tx_cmd = form_did_create_tx_multisig(did_doc_string, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering the DID with DID Id {did_doc_id}")

print("Registering a DID with invalid chain-id in blockchainAccountId")
print("3. FAIL: Registering a DID with invalid chain-id in blockchainAccountId")
kp = generate_key_pair(algo=kp_algo)
did_doc_string = generate_did_document(kp, kp_algo)
did_doc_id = did_doc_string["id"]
Expand All @@ -777,10 +802,147 @@ def caip10_cosmos_support_test():
"signing_algo": kp_algo
}
signers.append(signPair)

create_tx_cmd = form_did_create_tx_multisig(did_doc_string, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering DID with Id: {did_doc_id}", True, True)

print("4. PASS: Registering a DID with two VM of type EcdsaSecp256k1VerificationKey2019 with duplicate publicKeyMultibase and different blockchain account Id")
kp = generate_key_pair(algo=kp_algo)

did_doc_string_1 = generate_did_document(kp, kp_algo)
did_doc_string_2 = generate_did_document(kp, kp_algo, "osmo")
did_doc_string_2_vm = did_doc_string_2["verificationMethod"][0]
did_doc_string_2_vm["id"] = did_doc_string_2_vm["id"] + "new"

did_doc_string_1["verificationMethod"] = [
did_doc_string_1["verificationMethod"][0],
did_doc_string_2_vm,
]
did_doc_id = did_doc_string_1["id"]

signers = []
signPair1 = {
"kp": kp,
"verificationMethodId": did_doc_string_1["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signPair2 = {
"kp": kp,
"verificationMethodId": did_doc_string_2["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signers.append(signPair1)
signers.append(signPair2)
create_tx_cmd = form_did_create_tx_multisig(did_doc_string_1, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering the DID with DID Id {did_doc_id}")

print("5. PASS: Registering a DID with two VM of type EcdsaSecp256k1VerificationKey2019 with duplicate publicKeyMultibase but one of them is without a blockchain account id")
kp = generate_key_pair(algo=kp_algo)

did_doc_string_1 = generate_did_document(kp, kp_algo)
did_doc_string_2 = generate_did_document(kp, kp_algo)
did_doc_string_2_vm = did_doc_string_2["verificationMethod"][0]
did_doc_string_2_vm["id"] = did_doc_string_2_vm["id"] + "new"

#Remove blockchainAccountIds
did_doc_string_1["verificationMethod"][0]["blockchainAccountId"] = ""

did_doc_string_1["verificationMethod"] = [
did_doc_string_1["verificationMethod"][0],
did_doc_string_2_vm,
]
did_doc_id = did_doc_string_1["id"]

signers = []
signPair1 = {
"kp": kp,
"verificationMethodId": did_doc_string_1["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signPair2 = {
"kp": kp,
"verificationMethodId": did_doc_string_2["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signers.append(signPair1)
signers.append(signPair2)
create_tx_cmd = form_did_create_tx_multisig(did_doc_string_1, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering the DID with DID Id {did_doc_id}")

print("6. FAIL: Registering a DID with two VM of type EcdsaSecp256k1VerificationKey2019 with duplicate publicKeyMultibase and duplicate blockchainAccountId")
kp = generate_key_pair(algo=kp_algo)

did_doc_string_1 = generate_did_document(kp, kp_algo)
did_doc_string_2 = generate_did_document(kp, kp_algo)

did_doc_vm1 = did_doc_string_1["verificationMethod"][0]
did_doc_vm2 = did_doc_string_2["verificationMethod"][0]

# Change vm id
did_doc_vm1["id"] = did_doc_vm1["id"] + "news"
did_doc_vm2["id"] = did_doc_vm1["id"] + "2"


did_doc_string_1["verificationMethod"] = [
did_doc_vm1,
did_doc_vm2
]
did_doc_id = did_doc_string_1["id"]

signers = []
signPair1 = {
"kp": kp,
"verificationMethodId": did_doc_string_1["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signPair2 = {
"kp": kp,
"verificationMethodId": did_doc_string_1["verificationMethod"][1]["id"],
"signing_algo": kp_algo
}
signers.append(signPair1)
signers.append(signPair2)
create_tx_cmd = form_did_create_tx_multisig(did_doc_string_1, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering the DID with DID Id {did_doc_id}", True, True)

print("7. FAIL: Registering a DID with two VM of type EcdsaSecp256k1VerificationKey2019 with duplicate publicKeyMultibase and no blockchainAccountId in either of them")
kp = generate_key_pair(algo=kp_algo)

did_doc_string_1 = generate_did_document(kp, kp_algo)
did_doc_string_2 = generate_did_document(kp, kp_algo)

did_doc_vm1 = did_doc_string_1["verificationMethod"][0]
did_doc_vm2 = did_doc_string_2["verificationMethod"][0]

# Change vm id
did_doc_vm1["id"] = did_doc_vm1["id"] + "news"
did_doc_vm2["id"] = did_doc_vm1["id"] + "2"

# Remove blockchainAccountId
did_doc_vm1["blockchainAccountId"] = ""
did_doc_vm2["blockchainAccountId"] = ""

did_doc_string_1["verificationMethod"] = [
did_doc_vm1,
did_doc_vm2
]
did_doc_id = did_doc_string_1["id"]

signers = []
signPair1 = {
"kp": kp,
"verificationMethodId": did_doc_string_1["verificationMethod"][0]["id"],
"signing_algo": kp_algo
}
signPair2 = {
"kp": kp,
"verificationMethodId": did_doc_vm2["id"],
"signing_algo": kp_algo
}
signers.append(signPair1)
signers.append(signPair2)
create_tx_cmd = form_did_create_tx_multisig(did_doc_string_1, signers, DEFAULT_BLOCKCHAIN_ACCOUNT_NAME)
run_blockchain_command(create_tx_cmd, f"Registering the DID with DID Id {did_doc_id}", True, True)

print("--- Test Completed ---\n")

def vm_type_test():
Expand Down
13 changes: 10 additions & 3 deletions tests/e2e/ssi_tests/generate_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from utils import run_command, generate_document_id, get_document_signature, \
secp256k1_pubkey_to_address

def generate_did_document(key_pair, algo="ed25519"):
def generate_did_document(key_pair, algo="ed25519", bech32prefix="hid"):
base_document = {
"context" : [
"https://www.w3.org/ns/did/v1"
Expand Down Expand Up @@ -41,8 +41,15 @@ def generate_did_document(key_pair, algo="ed25519"):
verification_method["blockchainAccountId"] = "eip155:1:" + key_pair["ethereum_address"]
elif algo == "secp256k1":

verification_method["blockchainAccountId"] = "cosmos:jagrat:" + \
secp256k1_pubkey_to_address(key_pair["pub_key_base_64"], "hid")
if bech32prefix == "hid":
verification_method["blockchainAccountId"] = "cosmos:jagrat:" + \
secp256k1_pubkey_to_address(key_pair["pub_key_base_64"], bech32prefix)
elif bech32prefix == "osmo":
verification_method["blockchainAccountId"] = "cosmos:osmosis-1:" + \
secp256k1_pubkey_to_address(key_pair["pub_key_base_64"], bech32prefix)
else:
raise Exception("unsupported bech32 prefix " + bech32prefix)

verification_method["publicKeyMultibase"] = key_pair["pub_key_multibase"]
else:
verification_method["publicKeyMultibase"] = key_pair["pub_key_multibase"]
Expand Down
37 changes: 30 additions & 7 deletions x/ssi/types/diddoc_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ func verificationKeyCheck(vm *VerificationMethod) error {
return nil
}

// checkDuplicateId return a duplicate Id from the list, if found
func checkDuplicateId(list []string) string {
// checkDuplicateItems return a duplicate Id from the list, if found
func checkDuplicateItems(list []string) string {
presentMap := map[string]bool{}
for idx := range list {
if _, present := presentMap[list[idx]]; !present {
Expand Down Expand Up @@ -183,7 +183,7 @@ func validateServices(services []*Service) error {
for _, service := range services {
serviceIdList = append(serviceIdList, service.Id)
}
if duplicateId := checkDuplicateId(serviceIdList); duplicateId != "" {
if duplicateId := checkDuplicateItems(serviceIdList); duplicateId != "" {
return fmt.Errorf("duplicate service found with Id: %s ", duplicateId)
}

Expand Down Expand Up @@ -224,19 +224,42 @@ func validateVerificationMethods(vms []*VerificationMethod) error {
vmIdList := []string{}
publicKeyMultibaseList := []string{}
blockchainAccountIdList := []string{}

var pubKeyMultibaseBlockchainAccIdMap map[string]bool = map[string]bool{}

for _, vm := range vms {
vmIdList = append(vmIdList, vm.Id)
publicKeyMultibaseList = append(publicKeyMultibaseList, vm.PublicKeyMultibase)

if vm.Type == EcdsaSecp256k1VerificationKey2019 {
if _, present := pubKeyMultibaseBlockchainAccIdMap[vm.PublicKeyMultibase]; present {
// TODO: Following is a temporary measure, where we will be allowing duplicate publicKeyMultibase values
// for type EcdsaSecp256k1VerificationKey2019, provided if blockchainAccountId field is populated. This is done since
// one secp256k1 key pair from Keplr wallet can have multiple blockchain addresses depending upon the bech32
// prefix. This will eventually be removed once the successful recovery of public key from the `signEthereum()`
// generated signature is figured out.
if vm.BlockchainAccountId == "" {
return fmt.Errorf(
"duplicate publicKeyMultibase of type EcdsaSecp256k1VerificationKey2019 without blockchainAccountId is not allowed: %s ",
vm.PublicKeyMultibase,
)
}
} else {
pubKeyMultibaseBlockchainAccIdMap[vm.PublicKeyMultibase] = true
}
} else {
publicKeyMultibaseList = append(publicKeyMultibaseList, vm.PublicKeyMultibase)
}

blockchainAccountIdList = append(blockchainAccountIdList, vm.BlockchainAccountId)
}
if duplicateId := checkDuplicateId(vmIdList); duplicateId != "" {

if duplicateId := checkDuplicateItems(vmIdList); duplicateId != "" {
return fmt.Errorf("duplicate verification method Id found: %s ", duplicateId)
}
if duplicateKey := checkDuplicateId(publicKeyMultibaseList); duplicateKey != "" {
if duplicateKey := checkDuplicateItems(publicKeyMultibaseList); duplicateKey != "" {
return fmt.Errorf("duplicate publicKeyMultibase found: %s ", duplicateKey)
}
if duplicateKey := checkDuplicateId(blockchainAccountIdList); duplicateKey != "" {
if duplicateKey := checkDuplicateItems(blockchainAccountIdList); duplicateKey != "" {
return fmt.Errorf("duplicate blockchainAccountId found: %s ", duplicateKey)
}

Expand Down

0 comments on commit 0369721

Please sign in to comment.