verify method

Future<bool> verify(
  1. Map<String, Object?> record,
  2. TrustBundle trust
)

Implementation

Future<bool> verify(Map<String, Object?> record, TrustBundle trust) async {
  if (record['kind'] != 'zuke.external-attestation') {
    return false;
  }
  final signer = (record['signer'] as Map?)?.cast<String, Object?>();
  final body = (record['body'] as Map?)?.cast<String, Object?>();
  final signatureText = record['signature'];
  if (signer == null ||
      body == null ||
      signatureText is! String ||
      signer['algorithm'] != 'Ed25519') {
    return false;
  }
  for (final field in const [
    'providerId',
    'controlId',
    'target',
    'variant',
    'kind',
    'layer',
    'owner',
    'system',
    'reference',
    'scopeHash',
    'evidenceType',
    'evidenceDigest',
    'issuedAt',
    'expiresAt',
  ]) {
    if (body[field] is! String || (body[field] as String).isEmpty) {
      return false;
    }
  }
  if (!RegExp(
    r'^sha256:[a-f0-9]{64}$',
  ).hasMatch(body['evidenceDigest'] as String)) {
    return false;
  }
  final signerId = signer['signerId'];
  final keyId = signer['keyId'];
  if (signerId is! String || keyId is! String) return false;
  final key = trust.find(signerId, keyId, 'attestation');
  if (key == null) return false;
  final unsigned = <String, Object?>{
    'kind': record['kind'],
    'signer': signer,
    'body': body,
  };
  final bytes = attestationSigningPayload(unsigned);
  final signature = Signature(
    base64Decode(signatureText),
    publicKey: SimplePublicKey(key.publicKey, type: KeyPairType.ed25519),
  );
  return algorithm.verify(bytes, signature: signature);
}