Ejemplo n.º 1
0
    async def delete_pairwise(self, their_did: str) -> None:
        """
        Remove a pairwise DID record by its remote DID. Silently return if no such record is present.
        Raise WalletState for closed wallet, or BadIdentifier for invalid pairwise DID.

        :param their_did: remote DID marking pairwise DID to remove
        """

        LOGGER.debug('Wallet.delete_pairwise >>> their_did: %s', their_did)

        if not ok_did(their_did):
            LOGGER.debug('Wallet.delete_pairwise <!< Bad DID %s', their_did)
            raise BadIdentifier('Bad DID {}'.format(their_did))

        await self.delete_non_secret(TYPE_PAIRWISE, their_did)

        LOGGER.debug('Wallet.delete_pairwise <<<')
Ejemplo n.º 2
0
    async def get_local_did(self, loc: str) -> DIDInfo:
        """
        Get local DID info by local DID or verification key.
        Raise AbsentRecord for no such local DID.

        :param loc: DID or verification key of interest
        :return: DIDInfo for local DID
        """

        LOGGER.debug('Wallet.get_local_did >>> loc: %s', loc)

        if not self.handle:
            LOGGER.debug('Wallet.get_local_did <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        if ok_did(loc):  # it's a DID
            try:
                did_with_meta = json.loads(await did.get_my_did_with_meta(self.handle, loc))
                rv = DIDInfo(
                    did_with_meta['did'],
                    did_with_meta['verkey'],
                    json.loads(did_with_meta['metadata']) if did_with_meta['metadata'] else {})  # nudge None to empty
            except IndyError as x_indy:
                if x_indy.error_code == ErrorCode.WalletItemNotFound:
                    LOGGER.debug('Wallet.get_local_did <!< DID %s not present in wallet %s', loc, self.name)
                    raise AbsentRecord('Local DID {} not present in wallet {}'.format(loc, self.name))
                LOGGER.debug('Wallet.get_local_did <!< indy-sdk raised error %s', x_indy.error_code)
                raise

        else:  # it's a verkey
            dids_with_meta = json.loads(await did.list_my_dids_with_meta(self.handle))  # list
            for did_with_meta in dids_with_meta:
                if did_with_meta['verkey'] == loc:
                    rv = DIDInfo(
                        did_with_meta['did'],
                        did_with_meta['verkey'],
                        json.loads(did_with_meta['metadata']) if did_with_meta['metadata'] else {})
                    break
            else:
                LOGGER.debug('Wallet.get_local_did <!< Wallet %s has no local DID for verkey %s', self.name, loc)
                raise AbsentRecord('Wallet {} has no local DID for verkey {}'.format(self.name, loc))

        LOGGER.debug('Wallet.get_local_did <<< %s', rv)
        return rv
Ejemplo n.º 3
0
    async def set_did_endpoint(self, remote_did: str,
                               did_endpoint: str) -> EndpointInfo:
        """
        Set endpoint as metadata for pairwise remote DID in wallet. Pick up (transport)
        verification key from pairwise relation and return with endpoint in EndpointInfo.


        Raise BadIdentifier on bad DID. Raise WalletState if wallet is closed.
        Raise AbsentRecord if pairwise relation not present in wallet.

        :param remote_did: pairwise remote DID
        :param endpoint: value to set as endpoint in wallet and cache
        :return: endpoint and (transport) verification key
        """

        LOGGER.debug(
            'BaseAnchor.set_did_endpoint >>> remote_did: %s, did_endpoint: %s',
            remote_did, did_endpoint)

        if not ok_did(remote_did):
            LOGGER.debug('BaseAnchor.set_did_endpoint <!< Bad DID %s',
                         remote_did)
            raise BadIdentifier('Bad DID {}'.format(remote_did))

        pairwise_info = (await self.wallet.get_pairwise(remote_did)).get(
            remote_did, None)
        if not pairwise_info:
            LOGGER.debug(
                'BaseAnchor.set_did_endpoint <!< Anchor %s has no pairwise relation for remote DID %s',
                self.name, remote_did)
            raise AbsentRecord(
                'Anchor {} has no pairwise relation for remote DID {}'.format(
                    self.name, remote_did))

        await self.wallet.write_pairwise(pairwise_info.their_did,
                                         pairwise_info.their_verkey,
                                         pairwise_info.my_did,
                                         {'did_endpoint': did_endpoint})

        rv = EndpointInfo(did_endpoint, pairwise_info.their_verkey)

        LOGGER.debug('BaseAnchor.set_did_endpoint <<< %s', rv)
        return rv
Ejemplo n.º 4
0
    async def get_nym(self, target_did: str = None) -> str:
        """
        Get json cryptonym (including current verification key) for input (anchor) DID from ledger.
        Return empty production {} if the ledger has no such cryptonym.

        Raise BadLedgerTxn on failure. Raise WalletState if target DID is default (own DID) value but
        wallet does not have it (neither created nor opened since initialization).

        :param target_did: DID of cryptonym to fetch (default own DID)
        :return: cryptonym json
        """

        LOGGER.debug('BaseAnchor.get_nym >>> target_did: %s', target_did)

        if target_did and not ok_did(target_did):
            LOGGER.debug('BaseAnchor.get_nym <!< Bad DID %s', target_did)
            raise BadIdentifier('Bad DID {}'.format(target_did))

        if not (target_did or self.did):
            LOGGER.debug(
                'BaseAnchor.get_nym <!< Bad wallet state: DID for %s unavailable',
                self.wallet.name)
            raise WalletState(
                'Bad wallet state: DID for {} unavailable'.format(
                    self.wallet.name))

        rv = json.dumps({})
        get_nym_req = await ledger.build_get_nym_request(
            self.did, target_did or self.did)
        resp_json = await self._submit(get_nym_req)

        data_json = (json.loads(resp_json)
                     )['result']['data']  # it's double-encoded on the ledger
        if data_json:
            rv = data_json

        LOGGER.debug('BaseAnchor.get_nym <<< %s', rv)
        return rv
Ejemplo n.º 5
0
    async def get_pairwise(self, pairwise_filt: str = None) -> dict:
        """
        Return dict mapping each pairwise DID of interest in wallet to its pairwise info, or,
        for no filter specified, mapping them all. If wallet has no such item, return empty dict.

        :param pairwise_filt: remote DID of interest, or WQL json (default all)
        :return: dict mapping remote DIDs to PairwiseInfo
        """

        LOGGER.debug('Wallet.get_pairwise >>> pairwise_filt: %s', pairwise_filt)

        if not self.handle:
            LOGGER.debug('Wallet.get_pairwise <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        storecs = await self.get_non_secret(
            TYPE_PAIRWISE,
            pairwise_filt if not pairwise_filt or ok_did(pairwise_filt) else json.loads(pairwise_filt),
            canon_pairwise_wql)
        rv = {k: storage_record2pairwise_info(storecs[k]) for k in storecs}  # touch up tags, mute leading ~

        LOGGER.debug('Wallet.get_pairwise <<< %s', rv)
        return rv
Ejemplo n.º 6
0
    async def get_did_endpoint(self, remote_did: str) -> EndpointInfo:
        """
        Return endpoint info for remote DID.
        Raise BadIdentifier for bad remote DID. Raise WalletState if bypassing cache but wallet is closed.
        Raise AbsentRecord for no such endpoint.

        :param remote_did: pairwise remote DID
        :return: endpoint and (transport) verification key as EndpointInfo
        """

        LOGGER.debug('BaseAnchor.get_did_endpoint >>> remote_did: %s',
                     remote_did)

        if not ok_did(remote_did):
            LOGGER.debug('BaseAnchor.get_did_endpoint <!< Bad DID %s',
                         remote_did)
            raise BadIdentifier('Bad DID {}'.format(remote_did))

        if not self.wallet.handle:
            LOGGER.debug('BaseAnchor.get_did_endpoint <!< Wallet %s is closed',
                         self.wallet.name)
            raise WalletState('Wallet {} is closed'.format(self.wallet.name))

        pairwise_info = (await self.wallet.get_pairwise(remote_did)).get(
            remote_did, None)
        if not (pairwise_info and 'did_endpoint' in pairwise_info.metadata):
            LOGGER.debug(
                'BaseAnchor.get_did_endpoint <!< No endpoint for remote DID %s',
                remote_did)
            raise AbsentRecord(
                'No endpoint for remote DID {}'.format(remote_did))
        rv = EndpointInfo(pairwise_info.metadata['did_endpoint'],
                          pairwise_info.their_verkey)

        LOGGER.debug('BaseAnchor.get_did_endpoint <<< %s', rv)
        return rv
Ejemplo n.º 7
0
    async def send_nym(self, did: str, verkey: str = None, alias: str = None, role: Role = None) -> None:
        """
        Send input anchor's cryptonym (including public DID, verification key, plus optional alias and role)
        to the distributed ledger.

        Raise BadLedgerTxn on failure, BadIdentifier for bad DID, or BadRole for bad role.

        :param did: public DID to send to ledger
        :param verkey: optional anchor verification key
        :param alias: optional alias
        :param role: anchor role on the ledger (default value of USER)
        """

        LOGGER.debug(
            'AnchorSmith.send_nym >>> did: %s, verkey: %s, alias: %s, role: %s', did, verkey, alias, role)

        if not ok_did(did):
            LOGGER.debug('AnchorSmith.send_nym <!< Bad DID %s', did)
            raise BadIdentifier('Bad DID {}'.format(did))

        req_json = await ledger.build_nym_request(self.did, did, verkey, alias, (role or Role.USER).token())
        await self._sign_submit(req_json)

        LOGGER.debug('AnchorSmith.send_nym <<<')
Ejemplo n.º 8
0
    async def get_endpoint(self,
                           target_did: str = None,
                           from_cache: bool = True) -> str:
        """
        Get endpoint attribute for anchor having input DID (default own DID).
        Raise WalletState if target DID is default (own DID) value but wallet does not have it
        (neither created nor opened since initialization).

        :param target_did: DID of anchor for which to find endpoint attribute on ledger
        :param from_cache: check endpoint cache first before visiting ledger; always update cache with ledger value
        :return: endpoint attribute value, or None for no such value
        """

        LOGGER.debug(
            'BaseAnchor.get_endpoint >>> target_did: %s, from_cache: %s',
            target_did, from_cache)

        rv = None

        if not (target_did or self.did):
            LOGGER.debug(
                'BaseAnchor.get_endpoint <!< Bad wallet state: DID for %s unavailable',
                self.name)
            raise WalletState(
                'Bad wallet state: DID for {} unavailable'.format(self.name))

        target_did = target_did or self.did
        if not ok_did(target_did):
            LOGGER.debug('BaseAnchor.get_endpoint <!< Bad DID %s', target_did)
            raise BadIdentifier('Bad DID {}'.format(target_did))

        if from_cache:
            with ENDPOINT_CACHE.lock:
                if target_did in ENDPOINT_CACHE:
                    LOGGER.info(
                        'BaseAnchor.get_endpoint: got endpoint for %s from cache',
                        target_did)
                    rv = ENDPOINT_CACHE[target_did]
                    LOGGER.debug('BaseAnchor.get_endpoint <<< %s', rv)
                    return rv

        req_json = await ledger.build_get_attrib_request(
            self.did, target_did, 'endpoint', None, None)
        resp_json = await self._submit(req_json)

        data_json = (json.loads(resp_json)
                     )['result']['data']  # it's double-encoded on the ledger
        if data_json:
            rv = json.loads(data_json)['endpoint'].get('endpoint', None)
        else:
            LOGGER.info(
                '_AgentCore.get_endpoint: ledger query returned response with no data'
            )

        with ENDPOINT_CACHE.lock:
            if rv:
                ENDPOINT_CACHE[target_did] = rv
            else:
                ENDPOINT_CACHE.pop(target_did, None)
                assert target_did not in ENDPOINT_CACHE

        LOGGER.debug('BaseAnchor.get_endpoint <<< %s', rv)
        return rv
Ejemplo n.º 9
0
async def delete_tails(request: Request, ident: str, epoch: int) -> HTTPResponse:
    """
    Delete tails files by corresponding rev reg ids: all, by rev reg id, by cred def id, or by issuer DID.

    :param request: Sanic request structure
    :param ident: 'all' for no filter; rev reg id, cred def id, or issuer DID to filter by any such identifier
    :param epoch: current EPOCH time, must be within 5 minutes of current server time
    :return: empty text response
    """

    if not await is_current(int(epoch)):
        LOGGER.error('DELETE epoch %s in too far from current server time', epoch)
        return response.text('DELETE epoch {} is too far from current server time'.format(epoch), status=400)

    signature = request.body
    plain = '{}||{}'.format(epoch, ident)

    tsan = await MEM_CACHE.get('tsan')
    if not tsan.verify(plain, signature, tsan.did):
        LOGGER.error('DELETE signature failed to verify')
        return response.text('DELETE signature failed to verify', status=400)

    dir_tails = join(dirname(dirname(realpath(__file__))), 'tails')

    if ident == 'all':  # delete everything -- note that 'all' is not valid base58 so no case below can apply
        if isdir(dir_tails):
            rmtree(dir_tails)
        makedirs(dir_tails, exist_ok=True)

    elif ok_rev_reg_id(ident):  # it's a rev reg id
        path_tails = Tails.linked(dir_tails, ident)
        if path_tails and isfile(path_tails):
            unlink(path_tails)
            LOGGER.info('Deleted %s', path_tails)
        path_link = join(Tails.dir(dir_tails, ident), ident)
        if path_link and islink(path_link):
            unlink(path_link)
            LOGGER.info('Deleted %s', path_link)

    elif ok_cred_def_id(ident):  # it's a cred def id (starts with issuer DID)
        dir_cd_id = join(dir_tails, ident)
        if isdir(dir_cd_id):
            rmtree(dir_cd_id)
            LOGGER.info('Deleted %s', dir_cd_id)
        elif exists(dir_cd_id):  # non-dir is squatting on name reserved for dir: it's corrupt; remove it
            unlink(dir_cd_id)
            LOGGER.info('Deleted spurious non-directory %s', dir_cd_id)

    elif ok_did(ident):  # it's an issuer DID
        dirs_cd_id = {dirname(link) for link in Tails.links(dir_tails, ident)}
        for dir_cd_id in dirs_cd_id:
            if ok_cred_def_id(basename(dir_cd_id)):
                if isdir(dir_cd_id):
                    rmtree(dir_cd_id)
                    LOGGER.info('Deleted %s', dir_cd_id)
                elif exists(dir_cd_id):  # non-dir is squatting on name reserved for dir: it's corrupt; remove it
                    unlink(dir_cd_id)
                    LOGGER.info('Deleted spurious non-directory %s', dir_cd_id)

    else:
        LOGGER.error('Token %s is not a valid specifier for tails files', ident)
        return response.text('Token {} is not a valid specifier for tails files'.format(ident), status=400)

    LOGGER.info('Fulfilled DELETE request deleting tails files on filter %s', ident)
    return response.text('')
Ejemplo n.º 10
0
    def deserialize(cls, did_doc: dict) -> 'DIDDoc':
        """
        Construct DIDDoc object from dict representation.

        Raise BadIdentifier for bad DID. Raise AbsentDIDDocItem for missing mandatory item.

        :param did_doc: DIDDoc dict reprentation.
        :return: DIDDoc from input json.
        """

        rv = None
        if 'id' in did_doc:
            rv = DIDDoc(did_doc['id'])
        else:  # heuristic: get DID to serve as DID document identifier from first OK-looking public key
            for section in ('publicKey', 'authentication'):
                if rv is None and section in did_doc:
                    for key_spec in did_doc[section]:
                        try:
                            pubkey_did = canon_did(
                                resource(key_spec.get('id', '')))
                            if ok_did(pubkey_did):
                                rv = DIDDoc(pubkey_did)
                                break
                        except BadIdentifier:  # no identifier here, move on to next candidate
                            break
            if rv is None:
                LOGGER.debug(
                    'DIDDoc.deserialize <!< no identifier in DID document')
                raise AbsentDIDDocItem('No identifier in DID document')

        for pubkey in did_doc.get(
                'publicKey', {}
        ):  # include all public keys, authentication pubkeys by reference
            pubkey_type = PublicKeyType.get(pubkey['type'])
            authn = any(
                canon_ref(rv.did, ak) == canon_ref(rv.did, pubkey['id'])
                for ak in did_doc.get('authentication', '')
                if isinstance(ak, str))
            key = PublicKey(  # initialization canonicalizes id
                rv.did, pubkey['id'], pubkey[pubkey_type.specifier],
                pubkey_type, canon_did(pubkey['controller']), authn)
            rv.pubkey[key.id] = key

        for akey in did_doc.get('authentication',
                                {}):  # include embedded authentication keys
            if isinstance(akey, collections.Mapping):
                pubkey_type = PublicKeyType.get(akey['type'])
                key = PublicKey(  # initialization canonicalized id
                    rv.did, akey['id'], akey[pubkey_type.specifier],
                    pubkey_type, canon_did(akey['controller']), True)
                rv.pubkey[key.id] = key

        for service in did_doc.get('service', {}):
            endpoint = service['serviceEndpoint']
            svc = Service(  # initialization canonicalizes id
                rv.did,
                service.get(
                    'id',
                    canon_ref(rv.did,
                              'assigned-service-{}'.format(len(rv.service)),
                              ';')), service['type'],
                rv.add_service_pubkeys(service, 'recipientKeys'),
                rv.add_service_pubkeys(service,
                                       ['mediatorKeys', 'routingKeys']),
                canon_ref(rv.did, endpoint, ';') if ';' in endpoint else
                endpoint, service.get('priority', None))
            rv.service[svc.id] = svc

        return rv
Ejemplo n.º 11
0
async def test_box_ids():
    print(Ink.YELLOW('\n\n== Testing Box Identifier Checks =='))

    assert ok_did(
        'Q4zqM7aXqm7gDQkUVLng9h')  # quibble: not technically a box id
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng9I')
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng')

    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h')
    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9h')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9hx')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng90')

    assert ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:3:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h::bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2::1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0a')
    assert not ok_schema_id(
        'Q4zqM7aXqm7gDQkUVLng9I:2:bc-reg:1.0')  # I is not in base58

    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:0')  # protocol >= 1.4
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:4:CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h::CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9I:3:CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3::18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18z:0')
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18')  # protocol == 1.3

    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0:CL_ACCUM:1'
    )  # protocol >= 1.4
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:5:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:4:CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL::CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:NOT_CL:20:0:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20z:0:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20::CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0::1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0:CL_ACCUM:')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:0:CL_ACCUM')
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1'
    )  # protocol == 1.3
Ejemplo n.º 12
0
async def test_ids():
    print(Ink.YELLOW('\n\n== Testing Identifier Checks =='))

    assert ok_wallet_reft('49ad0727-8663-45ae-a115-12b09860f9c6')
    assert not ok_wallet_reft('Q4zqM7aXqm7gDQkUVLng9I')
    assert not ok_wallet_reft('49ad0727-45ae-a115-12b09860f9c6')
    print('\n\n== 1 == Wallet referent identifier checks pass OK')

    assert ok_did('Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng9I')  # 'I' not a base58 char
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng')  # too short
    print('\n\n== 2 == Distributed identifier checks pass OK')

    for value in (None, 'TRUSTEE', 'STEWARD', 'TRUST_ANCHOR', ''):
        assert ok_role(value)
    for value in (123, 'TRUSTY', 'STEW', 'ANCHOR', ' '):
        assert not ok_role(value)
    print('\n\n== 3 == Role identifier checks pass OK')

    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h')
    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9h')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9hx')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng90')
    print('\n\n== 4 == Tails hash identifier checks pass OK')

    assert ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:3:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h::bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2::1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0a')
    assert not ok_schema_id(
        'Q4zqM7aXqm7gDQkUVLng9I:2:bc-reg:1.0')  # I is not in base58
    print('\n\n== 5 == Schema identifier checks pass OK')

    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag')  # protocol >= 1.4
    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag'
    )  # long form
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                          'Q4zqM7aXqm7gDQkUVLng9h')  # issuer-did
    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:Q999999999999999999999:2:schema_name:1.0:tag',
        'Q4zqM7aXqm7gDQkUVLng9h')  # long form, issuer-did
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                              'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag',
        'Xxxxxxxxxxxxxxxxxxxxxx')  # long form, issuer-did
    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag'
    )  # long form
    assert not ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:Q4zqM7aXqm7gDQkUVLng9h:schema_name:1.0:tag'
    )  # no :2:
    assert not ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:QIIIIIIIII7gDQkUVLng9h:schema_name:1.0:tag'
    )  # I not base58
    assert not ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:QIIIIIIIII7gDQkUVLng9h:schema_name:v1.0:tag'
    )  # bad version
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:4:CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h::CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9I:3:CL:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3::18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18z:tag')
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18')  # protocol == 1.3
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                          'Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                              'Xxxxxxxxxxxxxxxxxxxxxx')
    assert ok_cred_def_id(
        rev_reg_id2cred_def_id(
            'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag:CL_ACCUM:1'
        ))
    print('\n\n== 6 == Credential definition identifier checks pass OK')

    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )  # protocol >= 1.4
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert ok_rev_reg_id(  # long form
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag:CL_ACCUM:1'
    )
    assert ok_rev_reg_id(  # long form
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:Q4zqM7aXqm7gDQkUVLng9h:2:schema_name:1.0:tag:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:5:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:4:CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL::CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:NOT_CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20z:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20::CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag::1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM')
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1'
    )  # protocol == 1.3
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')
    print('\n\n== 7 == Revocation registry identifier checks pass OK')
Ejemplo n.º 13
0
async def test_box_ids():
    print(Ink.YELLOW('\n\n== Testing Identifier Checks =='))

    assert ok_wallet_reft('49ad0727-8663-45ae-a115-12b09860f9c6')
    assert not ok_wallet_reft('Q4zqM7aXqm7gDQkUVLng9I')
    assert not ok_wallet_reft('49ad0727-45ae-a115-12b09860f9c6')

    assert ok_did(
        'Q4zqM7aXqm7gDQkUVLng9h')  # quibble: not technically a box id
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng9I')
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng')

    for value in (None, 'TRUSTEE', 'STEWARD', 'TRUST_ANCHOR', ''):
        assert ok_role(value)
    for value in (123, 'TRUSTY', 'STEW', 'ANCHOR', ' '):
        assert not ok_role(value)

    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h')
    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9h')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9hx')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng90')

    assert ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:3:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h::bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2::1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0a')
    assert not ok_schema_id(
        'Q4zqM7aXqm7gDQkUVLng9I:2:bc-reg:1.0')  # I is not in base58

    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag')  # protocol >= 1.4
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                          'Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                              'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:4:CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h::CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9I:3:CL:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3::18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18z:tag')
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18')  # protocol == 1.3
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                          'Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                              'Xxxxxxxxxxxxxxxxxxxxxx')

    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )  # protocol >= 1.4
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:5:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:4:CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL::CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:NOT_CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20z:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20::CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag::1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM')

    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1'
    )  # protocol == 1.3
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')

    assert ok_endpoint('10.0.0.2:9702')
    assert ok_endpoint('0.0.0.0:0')
    assert not ok_endpoint('canada.gc.ca:8088')
    assert not ok_endpoint(':37')
    assert not ok_endpoint('http://url-wrong')
    assert not ok_endpoint('2.3.4.5')
    assert not ok_endpoint('2.3.4:8080')
    assert not ok_endpoint('1.2.3.4:abc')
    assert not ok_endpoint('1.2.3.4:1234.56')
Ejemplo n.º 14
0
async def test_ids():
    print(Ink.YELLOW('\n\n== Testing Identifier Checks =='))

    assert ok_wallet_reft('49ad0727-8663-45ae-a115-12b09860f9c6')
    assert not ok_wallet_reft('Q4zqM7aXqm7gDQkUVLng9I')
    assert not ok_wallet_reft('49ad0727-45ae-a115-12b09860f9c6')
    print('\n\n== 1 == Wallet referent identifier checks pass OK')

    assert ok_did('Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng9I')  # 'I' not a base58 char
    assert not ok_did('Q4zqM7aXqm7gDQkUVLng')  # too short
    print('\n\n== 2 == Distributed identifier checks pass OK')

    for value in (None, 'TRUSTEE', 'STEWARD', 'TRUST_ANCHOR', ''):
        assert ok_role(value)
    for value in (123, 'TRUSTY', 'STEW', 'ANCHOR', ' '):
        assert not ok_role(value)
    print('\n\n== 3 == Role identifier checks pass OK')

    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h')
    assert Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9h')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9hx')
    assert not Tails.ok_hash('Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng90')
    print('\n\n== 4 == Tails hash identifier checks pass OK')

    assert ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:3:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h::bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:bc-reg:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2::1.0')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:')
    assert not ok_schema_id('Q4zqM7aXqm7gDQkUVLng9h:2:bc-reg:1.0a')
    assert not ok_schema_id(
        'Q4zqM7aXqm7gDQkUVLng9I:2:bc-reg:1.0')  # I is not in base58
    print('\n\n== 5 == Schema identifier checks pass OK')

    assert ok_cred_def_id(
        'Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag')  # protocol >= 1.4
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                          'Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18:tag',
                              'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:4:CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h::CL:18:0')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9I:3:CL:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3::18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:18:tag')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18z:tag')
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18')  # protocol == 1.3
    assert ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                          'Q4zqM7aXqm7gDQkUVLng9h')
    assert not ok_cred_def_id('Q4zqM7aXqm7gDQkUVLng9h:3:CL:18',
                              'Xxxxxxxxxxxxxxxxxxxxxx')
    print('\n\n== 6 == Credential definition identifier checks pass OK')

    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )  # protocol >= 1.4
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:5:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:4:CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL::CL:20:0:CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:NOT_CL:20:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20z:tag:CL_ACCUM:1'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20::CL_ACCUM:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag::1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:1')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM:'
    )
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:tag:CL_ACCUM')
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1'
    )  # protocol == 1.3
    assert ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'LjgpST2rjsoxYegQDRm7EL')
    assert not ok_rev_reg_id(
        'LjgpST2rjsoxYegQDRm7EL:4:LjgpST2rjsoxYegQDRm7EL:3:CL:20:CL_ACCUM:1',
        'Xxxxxxxxxxxxxxxxxxxxxx')
    print('\n\n== 7 == Revocation registry identifier checks pass OK')

    assert ok_endpoint('10.0.0.2:9702')
    assert ok_endpoint('0.0.0.0:0')
    assert not ok_endpoint('canada.gc.ca:8088')
    assert not ok_endpoint(':37')
    assert not ok_endpoint('http://url-wrong')
    assert not ok_endpoint('2.3.4.5')
    assert not ok_endpoint('2.3.4:8080')
    assert not ok_endpoint('1.2.3.4:abc')
    assert not ok_endpoint('1.2.3.4:1234.56')
    print('\n\n== 8 == Endpoint checks pass OK')