예제 #1
0
    async def get_box_ids_issued(self) -> str:
        """
        Return json object on lists of all unique box identifiers (schema identifiers,
        credential definition identifiers, and revocation registry identifiers) for
        all credential definitions and credentials issued; e.g.,

        ::

            {
                "schema_id": [
                    "R17v42T4pk...:2:tombstone:1.2",
                    ...
                ],
                "cred_def_id": [
                    "R17v42T4pk...:3:CL:19:tag",
                    ...
                ]
                "rev_reg_id": [
                    "R17v42T4pk...:4:R17v42T4pk...:3:CL:19:tag:CL_ACCUM:0",
                    "R17v42T4pk...:4:R17v42T4pk...:3:CL:19:tag:CL_ACCUM:1",
                    ...
                ]
            }

        An issuer must issue a credential definition to include its schema identifier
        in the returned values; the schema identifier in isolation belongs properly
        to an Origin, not necessarily to an Issuer.

        The operation may be useful for a Verifier anchor going off-line to seed its
        cache before doing so.

        :return: tuple of sets for schema ids, cred def ids, rev reg ids
        """

        LOGGER.debug('Issuer.get_box_ids_issued >>>')

        cd_ids = [d for d in listdir(self._dir_tails)
            if isdir(join(self._dir_tails, d)) and ok_cred_def_id(d, self.did)]
        s_ids = []
        for cd_id in cd_ids:
            try:
                s_ids.append(json.loads(await self.get_schema(cred_def_id2seq_no(cd_id)))['id'])
            except AbsentSchema:
                LOGGER.error(
                    'Issuer %s has issued cred def %s but no corresponding schema on ledger',
                    self.wallet.name,
                    cd_id)
        rr_ids = [basename(link) for link in Tails.links(self._dir_tails, self.did)]

        rv = json.dumps({
            'schema_id': s_ids,
            'cred_def_id': cd_ids,
            'rev_reg_id': rr_ids
        })
        LOGGER.debug('Issuer.get_box_ids_issued <<< %s', rv)
        return rv
예제 #2
0
    async def build_proof_req_json(self, cd_id2spec: dict) -> str:
        """
        Build and return indy-sdk proof request for input attributes and non-revocation intervals by cred def id.

        :param cd_id2spec: dict mapping cred def ids to:

            - (optionally) 'attrs': lists of names of attributes of interest (omit for all, empty list or None for none)
            - (optionally) '>=': (pred) inclusive int lower-bounds of interest (omit, empty list, or None for none)
            - (optionally) '>': (pred) exclusive int lower-bounds of interest (omit, empty list, or None for none)
            - (optionally) '<=': (pred) inclusive int upper-bounds of interest (omit, empty list, or None for none)
            - (optionally) '<': (pred) exclusive int upper-bounds of interest (omit, empty list, or None for none)
            - (optionally), 'interval': either
                - (2-tuple) pair of epoch second counts marking 'from' and 'to' timestamps, or
                - | single epoch second count to set 'from' and 'to' the same; default
                  | (now, now) for cred defs supporting revocation or None otherwise; e.g.,

        ::

            {
                'Vx4E82R17q...:3:CL:16:tag': {
                    'attrs': [  # request attrs 'name' and 'favouriteDrink' from this cred def's schema
                        'name',
                        'favouriteDrink'
                    ],
                    '>=': {  # request predicate score>=80 from this cred def
                        'score': 80
                    }
                    '<=': {  # request ranking <=10 from this cred def
                        'ranking': 10
                    }
                    'interval': 1528116008  # same instant for all attrs and preds of corresponding schema
                },
                'R17v42T4pk...:3:CL:19:tag': None,  # request all attrs, no preds, default intervals on all attrs
                'e3vc5K168n...:3:CL:23:tag': {},  # request all attrs, no preds, default intervals on all attrs
                'Z9ccax812j...:3:CL:27:tag': {  # request all attrs, no preds, this interval on all attrs
                    'interval': (1528112408, 1528116008)
                },
                '9cHbp54C8n...:3:CL:37:tag': {  # request no attrs and some predicates; specify interval
                    'attrs': [],  # or equivalently, 'attrs': None
                    '>=': {
                        'employees': '50'  # nicety: implementation converts to int for caller
                    },
                    '>=': {
                        'revenue': '10000000'  # nicety: implementation converts to int for caller
                        'ebidta': 0
                    }
                    'interval': (1528029608, 1528116008)
                },
                '6caBcmLi33...:3:CL:41:tag': {  # all attrs, one pred, default intervals to now on attrs & pred
                    '>': {
                        'regEpoch': 1514782800
                    }
                },
                ...
            }

        :return: indy-sdk proof request json
        """

        LOGGER.debug('Verifier.build_proof_req_json >>> cd_id2spec: %s',
                     cd_id2spec)

        cd_id2schema = {}
        now = int(time())
        rv = {
            'nonce': str(int(time())),
            'name': 'proof_req',
            'version': '0.0',
            'requested_attributes': {},
            'requested_predicates': {}
        }

        for cd_id in cd_id2spec:
            if not ok_cred_def_id(cd_id):
                LOGGER.debug(
                    'Verifier.build_proof_req_json <!< Bad cred def id %s',
                    cd_id)
                raise BadIdentifier('Bad cred def id {}'.format(cd_id))

            interval = None
            cred_def = json.loads(await self.get_cred_def(cd_id))
            seq_no = cred_def_id2seq_no(cd_id)
            cd_id2schema[cd_id] = json.loads(await self.get_schema(seq_no))

            if 'revocation' in cred_def['value']:
                fro_to = cd_id2spec[cd_id].get(
                    'interval',
                    (now, now)) if cd_id2spec[cd_id] else (now, now)
                interval = {
                    'from': fro_to if isinstance(fro_to, int) else min(fro_to),
                    'to': fro_to if isinstance(fro_to, int) else max(fro_to)
                }

            for attr in (cd_id2spec[cd_id].get(
                    'attrs', cd_id2schema[cd_id]['attrNames']) or []
                         if cd_id2spec[cd_id] else
                         cd_id2schema[cd_id]['attrNames']):
                attr_uuid = '{}_{}_uuid'.format(seq_no, canon(attr))
                rv['requested_attributes'][attr_uuid] = {
                    'name': attr,
                    'restrictions': [{
                        'cred_def_id': cd_id
                    }]
                }
                if interval:
                    rv['requested_attributes'][attr_uuid][
                        'non_revoked'] = interval

            for pred in Predicate:
                for attr in (cd_id2spec[cd_id].get(pred.value.math, {}) or {}
                             if cd_id2spec[cd_id] else {}):
                    pred_uuid = '{}_{}_{}_uuid'.format(seq_no, canon(attr),
                                                       pred.value.fortran)
                    try:
                        rv['requested_predicates'][pred_uuid] = {
                            'name':
                            attr,
                            'p_type':
                            pred.value.math,
                            'p_value':
                            Predicate.to_int(
                                cd_id2spec[cd_id][pred.value.math][attr]),
                            'restrictions': [{
                                'cred_def_id': cd_id
                            }]
                        }
                    except ValueError:
                        LOGGER.info(
                            'cannot build %s predicate on non-int bound %s for %s',
                            pred.value.fortran,
                            cd_id2spec[cd_id][pred.value.math][attr], attr)
                        continue  # int conversion failed - reject candidate
                    if interval:
                        rv['requested_predicates'][pred_uuid][
                            'non_revoked'] = interval

        LOGGER.debug('Verifier.build_proof_req_json <<< %s', json.dumps(rv))
        return json.dumps(rv)