verifyCredential function

Future<bool> verifyCredential(
  1. dynamic credential, {
  2. Erc1056? erc1056,
  3. RevocationRegistry? revocationRegistry,
  4. String? expectedChallenge,
  5. Signer signerSelector(
    1. String typeMatch,
    2. dynamic loadDocumentFunction(
      1. Uri url,
      2. LoadDocumentOptions? options
      )
    ) = _determineSignerForType,
  6. dynamic loadDocumentFunction(
    1. Uri url,
    2. LoadDocumentOptions? options
    ) = loadDocumentStrict,
})

Verifies the signature for the given credential.

If an erc1056 instance is given it is used to determine the current ethereum-Address behind a did.

If revocationRegistry is given and the credential contains a credentialStatus property, the revocation status is checked.

Implementation

Future<bool> verifyCredential(dynamic credential,
    {Erc1056? erc1056,
    RevocationRegistry? revocationRegistry,
    String? expectedChallenge,
    Signer Function(
            String typeMatch,
            Function(Uri url, LoadDocumentOptions? options)
                loadDocumentFunction)
        signerSelector = _determineSignerForType,
    Function(Uri url, LoadDocumentOptions? options) loadDocumentFunction =
        loadDocumentStrict}) async {
  Map<String, dynamic> credMap;
  if (credential is VerifiableCredential) {
    credMap = credential.toJson();
  } else {
    credMap = credentialToMap(credential);
  }
  if (!credMap.containsKey('proof')) {
    throw Exception('no proof section found');
  }

  // check for Revocation
  if (credMap.containsKey('credentialStatus')) {
    var credStatus = credMap['credentialStatus'];

    if (credStatus['type'] == 'EthereumRevocationList') {
      if (revocationRegistry != null) {
        revocationRegistry.setContract(credStatus['id']);
        var revoked = await revocationRegistry
            .isRevoked(getHolderDidFromCredential(credMap));
        if (revoked) throw RevokedException('Credential was revoked');
      }
      //else
      //{
      //   throw Exception('Revocation contract needed');
      // }
    } else if (credStatus['type'] == 'RevocationList2020Status') {
      var status = RevocationList2020Status.fromJson(credStatus);
      var res = await get(Uri.parse(status.revocationListCredential),
          headers: {'Accept': 'application/json'});
      var revCred = RevocationList2020Credential.fromJson(res.body);
      var verified = await verifyCredential(revCred);
      if (!verified) {
        throw Exception('could not verify RevocationListCredential');
      }

      var revoked = revCred.isRevoked(int.parse(status.revocationListIndex));
      if (revoked) {
        throw Exception('Credential is revoked');
      }
    } else {
      throw Exception('Unknown Status-method : ${credStatus['type']}');
    }
  }

  // determine issuer
  var issuerDid = getIssuerDidFromCredential(credential);
  if (erc1056 != null) issuerDid = await erc1056.identityOwner(issuerDid);

  // verify proof
  Map<String, dynamic> proof = credMap['proof'];
  var signer = signerSelector.call(proof['type'], loadDocumentFunction);
  credMap.remove('proof');
  var verified =
      signer.verify(proof, credMap, issuerDid, challenge: expectedChallenge);
  credMap['proof'] = proof;

  return verified;
}