RunValidationResult.cs
1 using System.Security.Cryptography; 2 3 namespace GUNRPG.Security; 4 5 public sealed class RunValidationResult 6 { 7 private readonly byte[] _finalStateHash; 8 9 public RunValidationResult( 10 Guid runId, 11 Guid playerId, 12 Guid serverId, 13 byte[] finalStateHash, 14 SignedRunValidation attestation) 15 { 16 RunId = runId; 17 PlayerId = playerId; 18 ServerId = serverId; 19 _finalStateHash = AuthorityCrypto.CloneAndValidateSha256Hash(finalStateHash); 20 if (attestation == null) throw new ArgumentNullException(nameof(attestation)); 21 if (attestation.Validation == null) 22 throw new ArgumentException("Attestation Validation must not be null.", nameof(attestation)); 23 if (attestation.Certificate == null) 24 throw new ArgumentException("Attestation Certificate must not be null.", nameof(attestation)); 25 if (attestation.Validation.RunId != runId) 26 throw new ArgumentException("Attestation RunId does not match RunId.", nameof(attestation)); 27 if (attestation.Validation.PlayerId != playerId) 28 throw new ArgumentException("Attestation PlayerId does not match PlayerId.", nameof(attestation)); 29 if (attestation.Validation.ServerId != serverId) 30 throw new ArgumentException("Attestation ServerId does not match ServerId.", nameof(attestation)); 31 if (attestation.Certificate.ServerId != serverId) 32 throw new ArgumentException("Attestation Certificate ServerId does not match ServerId.", nameof(attestation)); 33 if (!CryptographicOperations.FixedTimeEquals(attestation.Validation.FinalStateHash, _finalStateHash)) 34 throw new ArgumentException("Attestation FinalStateHash does not match FinalStateHash.", nameof(attestation)); 35 Attestation = attestation; 36 } 37 38 public Guid RunId { get; } 39 40 public Guid PlayerId { get; } 41 42 public Guid ServerId { get; } 43 44 public byte[] FinalStateHash => (byte[])_finalStateHash.Clone(); 45 46 public SignedRunValidation Attestation { get; } 47 48 public byte[] ComputeResultHash() => ComputeResultHash(this); 49 50 public static byte[] ComputeResultHash(RunValidationResult result) 51 { 52 ArgumentNullException.ThrowIfNull(result); 53 54 return ComputeResultHash( 55 result.RunId, 56 result.PlayerId, 57 result.ServerId, 58 result._finalStateHash); 59 } 60 61 internal static byte[] ComputeResultHash( 62 Guid runId, 63 Guid playerId, 64 Guid serverId, 65 byte[] finalStateHash) => 66 AuthorityCrypto.ComputeRunResultHash(runId, playerId, serverId, finalStateHash); 67 68 internal static byte[] ComputeResultHash(RunValidationSignature validation) 69 { 70 ArgumentNullException.ThrowIfNull(validation); 71 72 return ComputeResultHash( 73 validation.RunId, 74 validation.PlayerId, 75 validation.ServerId, 76 validation.FinalStateHash); 77 } 78 }