using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Paca.Mobile.Core;
using Xunit;
namespace Paca.Tests.Mobile;
///
/// RED TEAM ATTACK SUITE: P2P QR 페어링 및 미디어 무결성 적대적 공격 테스트
/// 1. 조작된 체크섬/토큰 주입 시 디코딩 거부
/// 2. 잘못된 프로토콜 프리픽스 및 악의적 URI 주입 방어
/// 3. 헤더 매직 바이트 위조(앞 4바이트만 맞고 바디가 절단된 Truncated 공격) 방어
///
public class MobileP2pAndMediaAdversarialTests
{
[Fact]
public void RedTeam_QrPayload_ChecksumTampering_MustReject()
{
var payload = new P2pQrPayload
{
Host = "192.168.1.100",
Port = 52100,
Token = "token-xyz-123",
DeviceName = "Desktop-PC"
};
var encoded = P2pQrPayloadCodec.Encode(payload);
// 페이로드 중간의 토큰 1글자 변조
var tampered = encoded.Replace("token-xyz-123", "token-EVIL-666");
var success = P2pQrPayloadCodec.TryDecode(tampered, out var decoded);
Assert.False(success, "[Red Team] 체크섬과 본문 내용이 불일치하는 변조된 QR 페이로드는 거부되어야 합니다.");
Assert.Null(decoded);
}
[Fact]
public void RedTeam_QrPayload_InvalidPrefix_Or_CorruptedUri_MustReject()
{
Assert.False(P2pQrPayloadCodec.TryDecode("http://attacker.com/fake-pair", out _));
Assert.False(P2pQrPayloadCodec.TryDecode("paca://invalid?h=1&p=bad&sig=000", out _));
Assert.False(P2pQrPayloadCodec.TryDecode("", out _));
Assert.False(P2pQrPayloadCodec.TryDecode(null!, out _));
}
[Fact]
public void RedTeam_MediaIntegrity_TruncatedPayload_MustDetectCorruption()
{
// MP4 매직 'ftyp'는 존재하지만 크기가 6바이트로 잘린 비정상 스트림
var truncatedMp4 = new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74 };
Assert.False(MediaIntegrityVerifier.ValidateMediaHeader(truncatedMp4, ".mp4"));
// 0바이트 파일
var zeroByteResult = MediaIntegrityVerifier.InspectIntegrity(Array.Empty(), "video.mp4");
Assert.False(zeroByteResult.IsValid);
Assert.Contains("0바이트", zeroByteResult.ErrorReason);
// 확장자와 내용물 불일치 공격 (WebM 헤더를 가진 파일을 .mp4로 위장)
var webmHeader = new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0x00, 0x00, 0x00, 0x00 };
var spoofResult = MediaIntegrityVerifier.InspectIntegrity(webmHeader, "fake_video.mp4");
Assert.False(spoofResult.IsValid, "[Red Team] 확장자(.mp4)와 실제 컨테이너(WebM) 헤더가 불일치하면 무결성 검증이 실패해야 합니다.");
}
[Fact]
public void RedTeam_MediaIntegrity_Sha256Tampering_MustDetect()
{
var validMp4 = new byte[64];
validMp4[4] = 0x66; validMp4[5] = 0x74; validMp4[6] = 0x79; validMp4[7] = 0x70; // ftyp
var correctHash = Convert.ToHexString(SHA256.HashData(validMp4)).ToLowerInvariant();
var forgedHash = correctHash.Substring(0, 60) + "dead"; // 끝 4자리 위조
var result = MediaIntegrityVerifier.InspectIntegrity(validMp4, "test.mp4", forgedHash);
Assert.False(result.IsValid);
Assert.False(result.ChecksumMatch);
Assert.Contains("불일치", result.ErrorReason);
}
}