Skip to content

Commit

Permalink
Merge pull request #8 from PsychoPunkSage/main
Browse files Browse the repository at this point in the history
fix::> Update network policy middle
  • Loading branch information
wiredhikari authored Mar 3, 2024
2 parents 3f108ed + 28bfdcc commit c924997
Show file tree
Hide file tree
Showing 2 changed files with 342 additions and 3 deletions.
51 changes: 50 additions & 1 deletion plenum/server/plugin/did_plugin/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,53 @@ def __init__(self, did_json) -> None:
def fetch_authentication_method(self) -> dict:
for method_id, method in self.authentication_methods.items():
if method["type"] == "BlockchainNetworkMultiSig":
return method
return method


class UPDATE_NETWORK_DID:
did = None
id = None
verification_methods = None
authentication_methods = None
network_participants: list = None

def __init__(self, did_json) -> None:
self.did = json.loads(did_json)
self.id = self.did["id"]
self.network_participants = self.did["networkMembers"]

assert(len(self.network_participants) > 0)

# populate verification methods:
self.verification_methods = {}
for method in self.did["verificationMethod"]:
self.verification_methods[method["id"]] = method

# populate authentication methods:
self.authentication_methods = {}
for method in self.did["authentication"]:
if isinstance(method, dict):
# fully specified method
self.authentication_methods[method["id"]] = method
elif isinstance(method, str):
# id points to a verification method
# TODO: if it points to a different did -> resolve that did and fetch method
if method in self.verification_methods:
self.authentication_methods[method] = self.verification_methods[method]

# ensure atleast one authentication method of type BlockchainNetworkMultiSig
group_multisig_auth_support = False
for method_id, method in self.authentication_methods.items():
if method["type"] == "BlockchainNetworkMultiSig":
group_multisig_auth_support = True
if not group_multisig_auth_support:
raise Exception("Network DID does not have BlockchainNetworkMultiSig authentication method")

# Get any one authentication method of type BlockchainNetworkMultiSig
def fetch_authentication_method(self) -> dict:
for method_id, method in self.authentication_methods.items():
if method["type"] == "BlockchainNetworkMultiSig":
return method

def to_be_updated_data(self,txn):
pass
294 changes: 292 additions & 2 deletions plenum/server/plugin/did_plugin/request_handlers/update_network_did.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from plenum.common.exceptions import InvalidClientRequest, MissingSignature, InvalidSignature

from plenum.server.database_manager import DatabaseManager
from plenum.server.plugin.did_plugin.constants import CREATE_NETWORK_DID
from plenum.server.plugin.did_plugin.constants import UPDATE_NETWORK_DID
from plenum.server.plugin.did_plugin.request_handlers.abstract_did_req_handler import AbstractDIDReqHandler
from plenum.server.plugin.did_plugin.common import DID, NetworkDID, did_id_from_url, libnacl_validate
from plenum.server.plugin.did_plugin.common import DID, NetworkDID, did_id_from_url, libnacl_validate, libnacl_validate2


from plenum.common.txn_util import get_payload_data, get_from, \
Expand All @@ -20,3 +20,293 @@
import libnacl
import libnacl.encode

"""
{
"SecurityDomainDIDDocument": {
"id": "did:<iin_name>:<network_name>",
"networkMembers": [
"did:<iin_name>:<network_member_1>",
"did:<iin_name>:<network_member_2>",
"did:<iin_name>:<network_member_3>"
],
"verificationMethod": [{
"id": "did:<iin_name>:<network_name>#multisig",
"type": "BlockchainNetworkMultiSig",
"controller": "did:<iin_name>:<network_name>",
"multisigKeys": [
"did:<iin_name>:<network_member_1>#key1",
"did:<iin_name>:<network_member_2>#key3",
"did:<iin_name>:<network_member_3>#key1"
],
"updatePolicy": {
"id": "did:<iin_name>:<network_name>#updatepolicy",
"controller": "did:<iin_name>:<network_name>",
"type": "VerifiableCondition2021",
"conditionAnd": [{
"id": "did:<iin_name>:<network_name>#updatepolicy-1",
"controller": "did:<iin_name>:<network_name>",
"type": "VerifiableCondition2021",
"conditionOr": ["did:<iin_name>:<network_member_3>#key1",
"did:<iin_name>:<network_member_2>#key3"
]
},
"did:<iin_name>:<network_member_1>#key1"
]
}
},
{
"id": "did:<iin_name>:<network_name>#fabriccerts",
"type": "DataplaneCredentials",
"controller": "did:<iin_name>:<network_name>",
"FabricCredentials": {
"did:<iin_name>:<network_member_1>": "Certificate3_Hash",
"did:<iin_name>:<network_member_2>": "Certificate2_Hash",
"did:<iin_name>:<network_member_3>": "Certificate3_Hash"
}
}
],
"authentication": [
"did:<iin_name>:<network_name>#multisig"
],
"relayEndpoints": [{
"hostname": "10.0.0.8",
"port": "8888"
},
{
"hostname": "10.0.0.9",
"port": "8888"
}
]
},
"signatures": {
"did:<iin_name>:<network_member_1>": "...",
"did:<iin_name>:<network_member_2>": "...",
"did:<iin_name>:<network_member_3>": "..."
}
}
"""



"""
<<<<NORMAL DID>>>>
"DIDDocument": {
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "did:iin:iin123:shippingcompany",
"verificationMethod": [
{
"id": "did:iin:iin123:shippingcompany#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase64": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}
],
"authentication": [
"did:iin:iin123:shippingcompany#keys-1",
{
"id": "did:iin:iin123:shippingcompany#keys-2",
"type": "Ed25519VerificationKey2020",
"controller": "did:shippingcompany",
"publicKeyBase64": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}
]
},
"""



class UpdateNetworkDIDRequest:
did: NetworkDID = None
did_str = None
signatures = None
this_indy_state = None
def __init__(self, request_dict: str, indy_state) -> None:
self.did_str = json.dumps(request_dict["DIDDocument"])
self.did = NetworkDID(self.did_str)
self.signatures = request_dict["signatures"]
self.this_indy_state = indy_state

def fetch_party_key_from_auth_method(self, party_did_id, auth_method):
for candidate_key_url in auth_method["multisigKeys"]:
base_url = did_id_from_url(candidate_key_url)
if base_url == party_did_id:
return candidate_key_url

def fetch_party_verification_method(self, party_key_url):
print("hello3")
party_did_id = did_id_from_url(party_key_url)
# Fetch party did
# TODO: if did is in some other iin network
# Will handle later...

# If did is in the same indy iin network
### TODO: did:iin:iin123:shippingcompany -----> DIDDocument: {....}

json_data = {
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": party_did_id,
"verificationMethod": [
{
"id": f"{party_did_id}#key1",
"type": "libnacl",
"controller": "did:example:123456789abcdefghi",
"publicKeyBase64": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z"
}
],
"authentication": [
f"{party_did_id}#key1",
{
"id": f"{party_did_id}#key1",
"type": "libnacl",
"controller": "did:shippingcompany",
"publicKeyBase64": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z"
}
]
}
json_string = json.dumps(json_data, indent=4)
party_did = DID(json_string)
party_authentication_method = party_did.fetch_authentication(party_key_url)

serialized_party_did = self.this_indy_state.get(party_did_id)
# if not serialized_party_did:
# raise "Could not resolve did " + party_did_id
print(serialized_party_did)
party_did = domain_state_serializer.deserialize(serialized_party_did)
party_did = DID(party_did)
party_authentication_method = party_did.fetch_authentication_method(party_key_url)
return party_authentication_method


def authenticate(self):
# Get any one authentication method of type GroupMultiSig
auth_method = self.did.fetch_authentication_method()

if not auth_method:
raise MissingSignature("Authentication verification method not found in SDDIDDocument.")
# Iterate of each participant
for party_did_id in self.did.network_participants:
# Fetch the key url from auth_method
party_key_url = self.fetch_party_key_from_auth_method(party_did_id, auth_method)
# Fetch verification key of the party
party_verification_method = self.fetch_party_verification_method(party_key_url)
# Validate signature of the party
if party_verification_method["type"] == "libnacl":
# validate signature
# TODO: Json serialization is not faithful. Use ordered collections isntead.
originalhash = libnacl.crypto_hash_sha256(self.did_str)
libnacl_validate(party_verification_method["publicKeyBase64"], self.signatures[party_did_id], originalhash)

# TODO: Add more authentication methods / some standard
else:
raise InvalidSignature("Unknown signature type: ", auth_method["type"])

class UpdateNetworkDIDHandler(AbstractDIDReqHandler):

def __init__(self, database_manager: DatabaseManager, did_dict: dict):
super().__init__(database_manager, UPDATE_NETWORK_DID, did_dict)

def additional_dynamic_validation(self, request: Request, req_pp_time: Optional[int]):
operation = request.operation
create_network_did_request_dict = operation.get(DATA)
# parse create did request
# try:
create_network_did_request = UpdateNetworkDIDRequest(create_network_did_request_dict, self.state)
# except:
# raise InvalidClientRequest(request.identifier, request.reqId, "Malformed CREATE_NETWORK_DID request.")

# TODO Check if the did uri corresponds to this iin or not.

# Check if did already in this iin or not.
serialized_did = self.state.get(create_network_did_request.did.id, isCommitted=True)
if serialized_did:
raise InvalidClientRequest(request.identifier, request.reqId, "DID already exists.")

# Authenticate
create_network_did_request.authenticate()


def update_state(self, txn, prev_result, request, is_committed=False):
"""
=> The `BlockchainNetworkMultiSig` verification method, and `networkMembers` list must be updated to reflect the new network membership.
- `networkMembers` is updated with the list of DIDs of the new network members.
- A new `update policy` is associated with the `BlockchainNetworkMultiSig` verification method.
=>
"""
data = get_payload_data(txn).get(DATA)
# What the hell is `data`
# print("data.....::>", data)

netwokMembers = []
multisig_keys = []
condition_or = []
signature = {}
sd_did_json = {
"SecurityDomainDIDDocument": {
"id": "did:<iin_name>:<network_name>",
"networkMembers": netwokMembers,
"verificationMethod": [
{
"id": "did:<iin_name>:<network_name>#multisig",
"type": "BlockchainNetworkMultiSig",
"controller": "did:<iin_name>:<network_name>",
"multisigKeys": multisig_keys,
"updatePolicy": {
"id": "did:<iin_name>:<network_name>#updatepolicy",
"controller": "did:<iin_name>:<network_name>",
"type": "VerifiableCondition2021",
"conditionAnd": [
{
"id": "did:<iin_name>:<network_name>#updatepolicy-1",
"controller": "did:<iin_name>:<network_name>",
"type": "VerifiableCondition2021",
"conditionOr": condition_or
},
"did:<iin_name>:<network_member_1>#key1"
]
}
},
{
"id": "did:<iin_name>:<network_name>#fabriccerts",
"type": "DataplaneCredentials",
"controller": "did:<iin_name>:<network_name>",
"FabricCredentials": {
"did:<iin_name>:<network_member_1>": "Certificate3_Hash",
"did:<iin_name>:<network_member_2>": "Certificate2_Hash",
"did:<iin_name>:<network_member_3>": "Certificate3_Hash"
}
}
],
"authentication": [
"did:<iin_name>:<network_name>#multisig"
],
"relayEndpoints": [
{
"hostname": "10.0.0.8",
"port": "8888"
},
{
"hostname": "10.0.0.9",
"port": "8888"
}
]
},
"signatures": signature
}
sd_did_json_string = json.dumps(sd_did_json, indent=4)
create_network_did_request = UpdateNetworkDIDRequest(sd_did_json_string, self.state)

self.did_dict[create_network_did_request.did.id] = create_network_did_request.did_str
key = create_network_did_request.did.id
val = self.did_dict[create_network_did_request.did.id]
print("Setting state:", key, val)
self.state.set(key.encode(), val)
return val

0 comments on commit c924997

Please sign in to comment.