authenticate method

  1. @override
Future<Principal> authenticate(
  1. Credential credential, {
  2. required Uint8List challenge,
})
override

Authenticates credential, returning the resolved principal.

Implementation

@override
Future<Principal> authenticate(
  Credential credential, {
  required Uint8List challenge,
}) async {
  final publicKeyBase64 = credential.publicKey;
  final signatureBase64 = credential.signature;
  if (publicKeyBase64 == null || signatureBase64 == null) {
    throw const AuthException('Missing public key or signature');
  }

  final Ed25519PublicKey publicKey;
  try {
    publicKey = Ed25519PublicKey.fromBase64(publicKeyBase64);
  } on Object {
    throw const AuthException('Malformed public key');
  }

  final entry = store.find(credential.principal, publicKey);
  if (entry == null) {
    throw const AuthException('Public key not authorized for principal');
  }

  final List<int> signatureBytes;
  try {
    signatureBytes = base64.decode(
      base64.normalize(_toStandard(signatureBase64)),
    );
  } on Object {
    throw const AuthException('Malformed signature');
  }

  final valid = await _algorithm.verify(
    challenge,
    signature: Signature(
      signatureBytes,
      publicKey: SimplePublicKey(publicKey.bytes, type: KeyPairType.ed25519),
    ),
  );
  if (!valid) {
    throw const AuthException('Signature verification failed');
  }

  return Principal(id: PrincipalId(credential.principal), roles: entry.roles);
}