From 373d254b6af7016b2855d521094de8b5bff5be3c Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Mon, 16 Jan 2023 21:01:51 +0300 Subject: [PATCH] Update Ini1Provider, make reliable package2 tests --- README.md | 2 +- .../other/System2/ini1/Ini1Provider.java | 20 +- .../RomFsDecrypted/Package2Test.java | 132 --------- .../RomFsDecrypted/Package2UnpackedTest.java | 253 ------------------ .../package2/ExtractPackage2Test.java | 143 ++++++++++ .../package2/Ini1ExtractTest.java | 155 +++++++++++ .../package2/KernelBinExtractTest.java | 149 +++++++++++ .../package2/Kip1ExtractTest.java | 156 +++++++++++ .../ExportNso0FromNcaTest.java | 2 +- .../KeyChainHolderTest.java | 2 +- .../NCAProviderSimpleTest.java | 2 +- .../NSODecompressTest.java | 2 +- .../{RomFsDecrypted => unsorted}/NSOTest.java | 2 +- .../NSPpfs0EncryptedTest.java | 2 +- .../PFS0Test.java | 2 +- .../Pfs0EncryptedTest.java | 2 +- .../RomFsDecryptedTest.java | 2 +- .../RomFsEncryptedTest.java | 2 +- .../{RomFsDecrypted => unsorted}/XciTest.java | 2 +- 19 files changed, 633 insertions(+), 399 deletions(-) delete mode 100644 src/test/java/libKonogonka/RomFsDecrypted/Package2Test.java delete mode 100644 src/test/java/libKonogonka/RomFsDecrypted/Package2UnpackedTest.java create mode 100644 src/test/java/libKonogonka/package2/ExtractPackage2Test.java create mode 100644 src/test/java/libKonogonka/package2/Ini1ExtractTest.java create mode 100644 src/test/java/libKonogonka/package2/KernelBinExtractTest.java create mode 100644 src/test/java/libKonogonka/package2/Kip1ExtractTest.java rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/ExportNso0FromNcaTest.java (98%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/KeyChainHolderTest.java (98%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/NCAProviderSimpleTest.java (98%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/NSODecompressTest.java (97%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/NSOTest.java (99%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/NSPpfs0EncryptedTest.java (99%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/PFS0Test.java (98%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/Pfs0EncryptedTest.java (99%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/RomFsDecryptedTest.java (99%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/RomFsEncryptedTest.java (99%) rename src/test/java/libKonogonka/{RomFsDecrypted => unsorted}/XciTest.java (98%) diff --git a/README.md b/README.md index 876eeff..8626b35 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,4 @@ See .drone.yml ### Install on local host (local maven repo) -`# mvn instal` \ No newline at end of file +`# mvn install` \ No newline at end of file diff --git a/src/main/java/libKonogonka/Tools/other/System2/ini1/Ini1Provider.java b/src/main/java/libKonogonka/Tools/other/System2/ini1/Ini1Provider.java index ab8bb6d..7994eac 100644 --- a/src/main/java/libKonogonka/Tools/other/System2/ini1/Ini1Provider.java +++ b/src/main/java/libKonogonka/Tools/other/System2/ini1/Ini1Provider.java @@ -22,6 +22,7 @@ import libKonogonka.Tools.ExportAble; import libKonogonka.Tools.other.System2.System2Header; import libKonogonka.ctraesclassic.InFileStreamClassicProducer; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,6 +35,14 @@ public class Ini1Provider extends ExportAble { private final InFileStreamClassicProducer producer; + public Ini1Provider(Path fileLocation) throws Exception{ + this.producer = new InFileStreamClassicProducer(fileLocation); + this.stream = producer.produce(); + makeHeader(); + collectKips(); + this.stream.close(); + } + public Ini1Provider(InFileStreamClassicProducer producer) throws Exception{ this.producer = producer; this.stream = producer.produce(); @@ -68,8 +77,7 @@ public class Ini1Provider extends ExportAble { long skipTillNextKip1 = 0; long kip1StartOffset = 0; for (int i = 0; i < ini1Header.getKipNumber(); i++){ - if (skipTillNextKip1 != stream.skip(skipTillNextKip1)) - throw new Exception("Unable to skip bytes till next KIP1 header"); + skipLoop(skipTillNextKip1); byte[] kip1bytes = new byte[0x100]; if (0x100 != stream.read(kip1bytes)) throw new Exception("Unable to read KIP1 data "); @@ -83,6 +91,14 @@ public class Ini1Provider extends ExportAble { kip1StartOffset = kip1.getEndOffset(); } } + private void skipLoop(long size) throws IOException { + long mustSkip = size; + long skipped = 0; + while (mustSkip > 0){ + skipped += stream.skip(mustSkip); + mustSkip = size - skipped; + } + } public Ini1Header getIni1Header() { return ini1Header; } public List getKip1List() { return kip1List; } diff --git a/src/test/java/libKonogonka/RomFsDecrypted/Package2Test.java b/src/test/java/libKonogonka/RomFsDecrypted/Package2Test.java deleted file mode 100644 index 8a1128b..0000000 --- a/src/test/java/libKonogonka/RomFsDecrypted/Package2Test.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - Copyright 2019-2022 Dmitry Isaenko - - This file is part of libKonogonka. - - libKonogonka is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - libKonogonka is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libKonogonka. If not, see . - */ -package libKonogonka.RomFsDecrypted; - -import libKonogonka.Converter; -import libKonogonka.KeyChainHolder; -import libKonogonka.RainbowDump; -import libKonogonka.Tools.NCA.NCAContent; -import libKonogonka.Tools.NCA.NCAProvider; -import libKonogonka.Tools.RomFs.FileSystemEntry; -import libKonogonka.Tools.RomFs.RomFsProvider; -import libKonogonka.ctraes.InFileStreamProducer; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.stream.Collectors; - -public class Package2Test { - - private static final String keysFileLocation = "./FilesForTests/prod.keys"; - private static final String xci_header_keyFileLocation = "./FilesForTests/xci_header_key.txt"; - private static final String ncaFileLocation = "/home/loper/Загрузки/patchesPlayground/fw1100"; - private static KeyChainHolder keyChainHolder; - private static NCAProvider ncaProvider; - - //@Disabled - @Order(1) - @DisplayName("Package2 Test") - @Test - void test() throws Exception{ - BufferedReader br = new BufferedReader(new FileReader(xci_header_keyFileLocation)); - String keyValue = br.readLine(); - br.close(); - - if (keyValue == null) - throw new Exception("Unable to retrieve xci_header_key"); - - keyValue = keyValue.trim(); - keyChainHolder = new KeyChainHolder(keysFileLocation, keyValue); - - File parent = new File(ncaFileLocation); - String[] dirWithFiles = parent.list((file, s) -> - s.endsWith(".nca") && !s.endsWith(".cnmt.nca")); //String[] dirWithFiles = parent.list((file, s) -> s.endsWith(".cnmt.nca")); - - Assertions.assertNotNull(dirWithFiles); - - for (String fileName : dirWithFiles){ - read(new File(ncaFileLocation + File.separator + fileName)); - } - } - - void read(File file) throws Exception{ - ncaProvider = new NCAProvider(file, keyChainHolder.getRawKeySet()); - - String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); - if (titleId.equals("0100000000000819")) - System.out.println(file.getName()+" "+titleId + "\tFAT"); - else if (titleId.equals("010000000000081b")) - System.out.println(file.getName()+" "+titleId + "\tEXFAT"); - else - return; - - if (ncaProvider.getSectionBlock0().getSuperBlockIVFC() == null) - return; - - RomFsProvider romFsProvider = ncaProvider.getNCAContentProvider(0).getRomfs(); - - FileSystemEntry package2Entry = romFsProvider.getRootEntry().getContent() - .stream() - .filter(fileSystemEntry -> fileSystemEntry.getName().equals("nx")) - .collect(Collectors.toList()) - .get(0) - .getContent() - .stream() - .filter(fileSystemEntry -> fileSystemEntry.getName().equals("package2")) - .collect(Collectors.toList()) - .get(0); - - System.out.println("NAME : "+package2Entry.getName()); - System.out.println("SIZE : "+package2Entry.getSize()); - System.out.println("OFFSET : "+package2Entry.getOffset()); - - //File tempDir = new File(System.getProperty("java.io.tmpdir")); - //File tempFile = File.createTempFile("pFilename", ".tmp", tempDir); - - romFsProvider.exportContent(System.getProperty("java.io.tmpdir"), package2Entry); - System.out.println(System.getProperty("java.io.tmpdir")); - - // . . . - - Files.delete(Paths.get(System.getProperty("java.io.tmpdir")+File.separator+"package2")); - - /* - int contentSize = 0x200; - InFileStreamProducer producer = romFsProvider.getStreamProducer( - romFsProvider.getRootEntry() - .getContent().get(0) - .getContent().get(2) - ); - - try (BufferedInputStream stream = producer.produce()){ - byte[] everythingCNMT = new byte[contentSize]; - Assertions.assertEquals(contentSize, stream.read(everythingCNMT)); - - RainbowDump.hexDumpUTF8(everythingCNMT); - } - */ - } -} diff --git a/src/test/java/libKonogonka/RomFsDecrypted/Package2UnpackedTest.java b/src/test/java/libKonogonka/RomFsDecrypted/Package2UnpackedTest.java deleted file mode 100644 index effc24f..0000000 --- a/src/test/java/libKonogonka/RomFsDecrypted/Package2UnpackedTest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - Copyright 2019-2022 Dmitry Isaenko - - This file is part of libKonogonka. - - libKonogonka is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - libKonogonka is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libKonogonka. If not, see . - */ -package libKonogonka.RomFsDecrypted; - -import libKonogonka.Converter; -import libKonogonka.KeyChainHolder; -import libKonogonka.Tools.NCA.NCAProvider; -import libKonogonka.Tools.RomFs.FileSystemEntry; -import libKonogonka.Tools.RomFs.RomFsProvider; -import libKonogonka.Tools.other.System2.System2Provider; -import libKonogonka.Tools.other.System2.ini1.Ini1Provider; -import libKonogonka.Tools.other.System2.ini1.KIP1Provider; -import libKonogonka.ctraes.InFileStreamProducer; -import libKonogonka.ctraesclassic.AesCtrDecryptClassic; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; - -public class Package2UnpackedTest { - - private static final String keysFileLocation = "./FilesForTests/prod.keys"; - private static final String xci_header_keyFileLocation = "./FilesForTests/xci_header_key.txt"; - private static KeyChainHolder keyChainHolder; - - private static final String fileLocation = "/home/loper/Projects/libKonogonka/FilesForTests/6b7abe7efa17ad065b18e62d1c87a5cc.nca_extracted/ROOT/nx/package2"; - - final String pathToFirmware = "/home/loper/Загрузки/patchesPlayground/nintendo-switch-global-firmwares/Firmware 14.1.0"; - - @DisplayName("Package2 unpacked test") - @Test - void discover() throws Exception{ - BufferedReader br = new BufferedReader(new FileReader(xci_header_keyFileLocation)); - String keyValue = br.readLine(); - br.close(); - - Assertions.assertNotNull(keyValue); - - keyValue = keyValue.trim(); - keyChainHolder = new KeyChainHolder(keysFileLocation, keyValue); - - HashMap rawKeys = keyChainHolder.getRawKeySet(); - - HashMap package2_keys = new HashMap<>(); - - for (String key: rawKeys.keySet()){ - if (key.matches("package2_key_[0-f][0-f]")) - package2_keys.put(key, rawKeys.get(key)); - } - - Assertions.assertNotNull(package2_keys); - - Path package2Path = Paths.get(fileLocation); - byte[] header; - - try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(package2Path))){ - Assertions.assertEquals(0x100, stream.skip(0x100)); - header = new byte[0x100]; - Assertions.assertEquals(0x100, stream.read(header)); - } - - Assertions.assertNotNull(header); - - byte[] headerCTR = Arrays.copyOfRange(header, 0, 0x10); - - for (Map.Entry entry: package2_keys.entrySet()){ - AesCtrDecryptClassic aesCtrClassic = new AesCtrDecryptClassic(entry.getValue(), headerCTR); - - byte[] decrypted = aesCtrClassic.decryptNext(header); - //RainbowDump.hexDumpUTF8(decrypted); - byte[] magic = Arrays.copyOfRange(decrypted, 0x50, 0x54); - String magicString = new String(magic, StandardCharsets.US_ASCII); - if (magicString.equals("PK21")) - System.out.println(entry.getKey()+" "+entry.getValue()+" "+magicString); - } - } - @DisplayName("Package2 written test") - @Test - void implement() throws Exception{ - System.out.printf("SIZE: %d 0x%x\n", Files.size(Paths.get(fileLocation)), Files.size(Paths.get(fileLocation))); - keyChainHolder = new KeyChainHolder(keysFileLocation, null); - System2Provider provider = new System2Provider(fileLocation, keyChainHolder); - provider.getHeader().printDebug(); - provider.getKernelMap().printDebug(); - Ini1Provider ini1Provider = provider.getIni1Provider(); - ini1Provider.getIni1Header().printDebug(); - for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) - kip1Provider.printDebug(); - boolean exported = provider.exportKernel("/home/loper/Projects/libKonogonka/FilesForTests/own/"); - System.out.println("Exported = "+exported); - - exported = ini1Provider.export("/home/loper/Projects/libKonogonka/FilesForTests/own/"); - System.out.println("Exported INI1 = "+exported); - - for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) { - exported = kip1Provider.export("/home/loper/Projects/libKonogonka/FilesForTests/own/KIP1s"); - System.out.println("Exported KIP1s "+ kip1Provider.getHeader().getName() +" = " + exported + - String.format(" Size 0x%x", Files.size(Paths.get("/home/loper/Projects/libKonogonka/FilesForTests/own/KIP1s/"+ kip1Provider.getHeader().getName()+".kip1")))); - } - } - - @DisplayName("KIP1 unpack test") - @Test - void unpackKip1FromNca() throws Exception{ - keyChainHolder = new KeyChainHolder(keysFileLocation, null); - // ------------------------------------------------------------------------------------------------------------ - File firmware = new File(pathToFirmware); - - if (! firmware.exists()) - throw new Exception("Firmware directory does not exist " + pathToFirmware); - - String[] fileNamesArray = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca"))); - List ncaFilesList = Arrays.asList(Objects.requireNonNull(fileNamesArray)); - if (ncaFilesList.size() == 0) - throw new Exception("No NCA files found in firmware folder"); - - List ncaProviders = new ArrayList<>(); - - for (String ncaFileName : fileNamesArray){ - File nca = new File(firmware.getAbsolutePath()+File.separator+ncaFileName); - NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet()); - ncaProviders.add(provider); - } - // ------------------------------------------------------------------------------------------------------------ - - NCAProvider system2FatNcaProvider = null; - NCAProvider system2ExFatNcaProvider = null; - for (NCAProvider ncaProvider : ncaProviders) { - String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); - if (titleId.equals("0100000000000819")) - system2FatNcaProvider = ncaProvider; - if (titleId.equals("010000000000081b")) - system2ExFatNcaProvider = ncaProvider; - } - System.out.println("FAT " + (system2FatNcaProvider == null ? "NOT FOUND": "FOUND")); - System.out.println("ExFAT " + (system2ExFatNcaProvider == null ? "NOT FOUND": "FOUND")); - - - RomFsProvider romFsExFatProvider = null; - FileSystemEntry exFatPackage2Content = null; - InFileStreamProducer producerExFat = null; - if (system2ExFatNcaProvider != null){ - romFsExFatProvider = system2ExFatNcaProvider.getNCAContentProvider(0).getRomfs(); - exFatPackage2Content = romFsExFatProvider.getRootEntry().getContent() - .stream() - .filter(e -> e.getName().equals("nx")) - .collect(Collectors.toList()) - .get(0) - .getContent() - .stream() - .filter(e -> e.getName().equals("package2")) - .collect(Collectors.toList()) - .get(0); - producerExFat = romFsExFatProvider.getStreamProducer(exFatPackage2Content); - - system2ExFatNcaProvider.getNCAContentProvider(0).getRomfs().getRootEntry().printTreeForDebug(); - romFsExFatProvider.exportContent("/tmp/exported_ExFat", exFatPackage2Content); - - System2Provider provider = new System2Provider(producerExFat, keyChainHolder); - provider.getKernelMap().printDebug(); - Ini1Provider ini1Provider = provider.getIni1Provider(); - KIP1Provider fsProvider = null; - - for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) - if (kip1Provider.getHeader().getName().startsWith("FS")) - fsProvider = kip1Provider; - - if (fsProvider != null) { - fsProvider.printDebug(); - fsProvider.exportAsDecompressed("/tmp/FAT_kip1"); - } - else - System.out.println("FS KIP1 NOT FOUND"); - } - - RomFsProvider romFsFatProvider = null; - FileSystemEntry fatPackage2Content = null; - InFileStreamProducer producerFat; - if (system2FatNcaProvider != null){ - romFsFatProvider = system2FatNcaProvider.getNCAContentProvider(0).getRomfs(); - - fatPackage2Content = romFsFatProvider.getRootEntry().getContent() - .stream() - .filter(e -> e.getName().equals("nx")) - .collect(Collectors.toList()) - .get(0) - .getContent() - .stream() - .filter(e -> e.getName().equals("package2")) - .collect(Collectors.toList()) - .get(0); - producerFat = romFsFatProvider.getStreamProducer(fatPackage2Content); - System2Provider provider = new System2Provider(producerFat, keyChainHolder); - provider.getKernelMap().printDebug(); - Ini1Provider ini1Provider = provider.getIni1Provider(); - KIP1Provider fsProvider = null; - - for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) - if (kip1Provider.getHeader().getName().startsWith("FS")) - fsProvider = kip1Provider; - - if (fsProvider != null) { - fsProvider.printDebug(); - fsProvider.exportAsDecompressed("/tmp/FAT_kip1"); - } - else - System.out.println("FS KIP1 NOT FOUND"); - } - } - - @DisplayName("KIP1 unpack test") - @Test - void unpackKip1() throws Exception{ - System2Provider provider = new System2Provider(fileLocation, keyChainHolder); - provider.getKernelMap().printDebug(); - Ini1Provider ini1Provider = provider.getIni1Provider(); - KIP1Provider fsProvider = null; - - for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) - if (kip1Provider.getHeader().getName().startsWith("FS")) - fsProvider = kip1Provider; - - if (fsProvider != null) { - fsProvider.printDebug(); - fsProvider.exportAsDecompressed("/tmp"); - } - else - System.out.println("FS KIP1 NOT FOUND"); - } -} diff --git a/src/test/java/libKonogonka/package2/ExtractPackage2Test.java b/src/test/java/libKonogonka/package2/ExtractPackage2Test.java new file mode 100644 index 0000000..cc04fcd --- /dev/null +++ b/src/test/java/libKonogonka/package2/ExtractPackage2Test.java @@ -0,0 +1,143 @@ +package libKonogonka.package2; + +import libKonogonka.Converter; +import libKonogonka.KeyChainHolder; +import libKonogonka.Tools.NCA.NCAProvider; +import libKonogonka.Tools.RomFs.FileSystemEntry; +import libKonogonka.Tools.RomFs.RomFsProvider; +import org.junit.jupiter.api.*; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.CRC32; + +/* ..::::::::::::::::::::: # 1 :::::::::::::::::::::.. +* This test validates (encrypted) package2 CRC32 equality and sizes match between reference values and +* 1. package2 from RomFS exported root +* 2. package2 from RomFS exported as stand-alone file +* */ + +public class ExtractPackage2Test { + final String KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"prod.keys"; + final String XCI_HEADER_KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"xci_header_key.txt"; + + final String pathToFirmware = "FilesForTests"+File.separator+"Firmware 14.1.0"; + + private static KeyChainHolder keyChainHolder; + + final String referenceFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"FAT"; + final String referenceExFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"ExFAT"; + final String exportFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_FAT"+File.separator+getClass().getSimpleName(); + final String exportExFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_ExFAT"+File.separator+getClass().getSimpleName(); + + @DisplayName("Extract package2 test") + @Test + void testSystem2() throws Exception{ + makeKeys(); + String[] ncaFileNames = collectNcaFileNames(); + List ncaProviders = makeNcaProviders(ncaFileNames); + + NCAProvider system2FatNcaProvider = null; + NCAProvider system2ExFatNcaProvider = null; + + for (NCAProvider ncaProvider : ncaProviders) { + String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); + if (titleId.equals("0100000000000819")) + system2FatNcaProvider = ncaProvider; + else if (titleId.equals("010000000000081b")) + system2ExFatNcaProvider = ncaProvider; + } + + Assertions.assertNotNull(system2FatNcaProvider); + Assertions.assertNotNull(system2ExFatNcaProvider); + + System.out.println("FAT " + system2FatNcaProvider.getFile().getName()); + System.out.println("ExFAT " + system2ExFatNcaProvider.getFile().getName()); + + Assertions.assertTrue(system2FatNcaProvider.getFile().getName().endsWith("1212c.nca")); + Assertions.assertTrue(system2ExFatNcaProvider.getFile().getName().endsWith("cc081.nca")); + + testExportedFiles(system2FatNcaProvider, exportFat, referenceFat); + testExportedFiles(system2ExFatNcaProvider, exportExFat, referenceExFat); + } + void makeKeys() throws Exception{ + String keyValue = new String(Files.readAllBytes(Paths.get(XCI_HEADER_KEYS_FILE_LOCATION))).trim(); + Assertions.assertNotEquals(0, keyValue.length()); + keyChainHolder = new KeyChainHolder(KEYS_FILE_LOCATION, keyValue); + } + String[] collectNcaFileNames(){ + File firmware = new File(pathToFirmware); + Assertions.assertTrue(firmware.exists()); + String[] ncaFileNames = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca"))); + Assertions.assertNotNull(ncaFileNames); + return ncaFileNames; + } + List makeNcaProviders(String[] ncaFileNames) throws Exception{ + List ncaProviders = new ArrayList<>(); + for (String ncaFileName : ncaFileNames){ + File nca = new File(pathToFirmware+File.separator+ncaFileName); + NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet()); + ncaProviders.add(provider); + } + + Assertions.assertNotEquals(0, ncaProviders.size()); + + return ncaProviders; + } + + void testExportedFiles(NCAProvider system2NcaProvider, String exportIntoFolder, String referenceFilesFolder) throws Exception{ + RomFsProvider romFsProvider = system2NcaProvider.getNCAContentProvider(0).getRomfs(); + + Path referenceFilePath = Paths.get(referenceFilesFolder+File.separator+"romfs"+File.separator+"nx"+File.separator+"package2"); + Path myFilePath1 = Paths.get(exportIntoFolder+File.separator+"ROOT"+File.separator+"nx"+File.separator+"package2"); + Path myFilePath2 = Paths.get(exportIntoFolder+File.separator+"package2"); + + System.out.println(); + System.out.println("Reference : " + referenceFilePath); + System.out.println("Own #1 : " + myFilePath1); + System.out.println("Own #2 : " + myFilePath2); + + romFsProvider.exportContent(exportIntoFolder, romFsProvider.getRootEntry()); + long referenceCrc32 = calculateReferenceCRC32(referenceFilePath); + validateChecksums(myFilePath1, referenceCrc32); + validateSizes(referenceFilePath, myFilePath1); + + FileSystemEntry package2FileSystemEntry = romFsProvider.getRootEntry().getContent() + .stream() + .filter(e -> e.getName().equals("nx")) + .collect(Collectors.toList()) + .get(0) + .getContent() + .stream() + .filter(e -> e.getName().equals("package2")) + .collect(Collectors.toList()) + .get(0); + + romFsProvider.exportContent(exportIntoFolder, package2FileSystemEntry); + validateChecksums(myFilePath2, referenceCrc32); + validateSizes(referenceFilePath, myFilePath2); + } + long calculateReferenceCRC32(Path refPackage2Path) throws Exception{ + byte[] refPackage2Bytes = Files.readAllBytes(refPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(refPackage2Bytes, 0, refPackage2Bytes.length); + return crc32.getValue(); + } + + void validateChecksums(Path myPackage2Path, long refPackage2Crc32) throws Exception{ + // Check CRC32 for package2 file only + byte[] myPackage2Bytes = Files.readAllBytes(myPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(myPackage2Bytes, 0, myPackage2Bytes.length); + long myPackage2Crc32 = crc32.getValue(); + Assertions.assertEquals(myPackage2Crc32, refPackage2Crc32); + } + + void validateSizes(Path a, Path b) throws Exception{ + Assertions.assertEquals(Files.size(a), Files.size(b)); + } +} diff --git a/src/test/java/libKonogonka/package2/Ini1ExtractTest.java b/src/test/java/libKonogonka/package2/Ini1ExtractTest.java new file mode 100644 index 0000000..90c1c4b --- /dev/null +++ b/src/test/java/libKonogonka/package2/Ini1ExtractTest.java @@ -0,0 +1,155 @@ +package libKonogonka.package2; + +import libKonogonka.Converter; +import libKonogonka.KeyChainHolder; +import libKonogonka.Tools.NCA.NCAProvider; +import libKonogonka.Tools.RomFs.FileSystemEntry; +import libKonogonka.Tools.RomFs.RomFsProvider; +import libKonogonka.Tools.other.System2.System2Provider; +import libKonogonka.Tools.other.System2.ini1.Ini1Provider; +import libKonogonka.ctraes.InFileStreamProducer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.CRC32; + +/* ..::::::::::::::::::::: # 3 :::::::::::::::::::::.. +* This test validates INI1.bin CRC32 equality and sizes match between reference values and +* 1. INI1.bin extracted from package2 file +* 2. INI1.bin extracted from NCA file via streams +* */ + +public class Ini1ExtractTest { + final String KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"prod.keys"; + final String XCI_HEADER_KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"xci_header_key.txt"; + + final String pathToFirmware = "FilesForTests"+File.separator+"Firmware 14.1.0"; + + private static KeyChainHolder keyChainHolder; + + final String referenceFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"FAT"; + final String referenceExFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"ExFAT"; + final String exportFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_FAT"+File.separator+getClass().getSimpleName(); + final String exportExFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_ExFAT"+File.separator+getClass().getSimpleName(); + + @DisplayName("INI1.bin extract test") + @Test + void testSystem2() throws Exception{ + makeKeys(); + String[] ncaFileNames = collectNcaFileNames(); + List ncaProviders = makeNcaProviders(ncaFileNames); + + NCAProvider system2FatNcaProvider = null; + NCAProvider system2ExFatNcaProvider = null; + + for (NCAProvider ncaProvider : ncaProviders) { + String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); + if (titleId.equals("0100000000000819")) + system2FatNcaProvider = ncaProvider; + else if (titleId.equals("010000000000081b")) + system2ExFatNcaProvider = ncaProvider; + } + + Assertions.assertNotNull(system2FatNcaProvider); + Assertions.assertNotNull(system2ExFatNcaProvider); + + System.out.println("FAT " + system2FatNcaProvider.getFile().getName()); + System.out.println("ExFAT " + system2ExFatNcaProvider.getFile().getName()); + + Assertions.assertTrue(system2FatNcaProvider.getFile().getName().endsWith("1212c.nca")); + Assertions.assertTrue(system2ExFatNcaProvider.getFile().getName().endsWith("cc081.nca")); + + testExportedFiles(system2FatNcaProvider, exportFat, referenceFat); + testExportedFiles(system2ExFatNcaProvider, exportExFat, referenceExFat); + } + void makeKeys() throws Exception{ + String keyValue = new String(Files.readAllBytes(Paths.get(XCI_HEADER_KEYS_FILE_LOCATION))).trim(); + Assertions.assertNotEquals(0, keyValue.length()); + keyChainHolder = new KeyChainHolder(KEYS_FILE_LOCATION, keyValue); + } + String[] collectNcaFileNames(){ + File firmware = new File(pathToFirmware); + Assertions.assertTrue(firmware.exists()); + String[] ncaFileNames = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca"))); + Assertions.assertNotNull(ncaFileNames); + return ncaFileNames; + } + List makeNcaProviders(String[] ncaFileNames) throws Exception{ + List ncaProviders = new ArrayList<>(); + for (String ncaFileName : ncaFileNames){ + File nca = new File(pathToFirmware+File.separator+ncaFileName); + NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet()); + ncaProviders.add(provider); + } + + Assertions.assertNotEquals(0, ncaProviders.size()); + + return ncaProviders; + } + + void testExportedFiles(NCAProvider system2NcaProvider, String exportIntoFolder, String referenceFilesFolder) throws Exception{ + RomFsProvider romFsProvider = system2NcaProvider.getNCAContentProvider(0).getRomfs(); + + FileSystemEntry package2FileSystemEntry = romFsProvider.getRootEntry().getContent() + .stream() + .filter(e -> e.getName().equals("nx")) + .collect(Collectors.toList()) + .get(0) + .getContent() + .stream() + .filter(e -> e.getName().equals("package2")) + .collect(Collectors.toList()) + .get(0); + + Path referenceFilePath = Paths.get(referenceFilesFolder+File.separator+"package2"+File.separator+"INI1.bin"); + Path myFilePath = Paths.get(exportIntoFolder+File.separator+"INI1.bin"); + + System.out.println(); + System.out.println("Reference : " + referenceFilePath); + System.out.println("Own : " + myFilePath); + long referenceCrc32 = calculateReferenceCRC32(referenceFilePath); + + romFsProvider.exportContent(exportIntoFolder, package2FileSystemEntry); + System2Provider kernelProviderFile = new System2Provider(exportIntoFolder+File.separator+"package2", keyChainHolder); + Ini1Provider ini1Provider = new Ini1Provider( + kernelProviderFile.getHeader(), + exportIntoFolder+File.separator+"package2", + kernelProviderFile.getKernelMap().getIni1Offset()); + ini1Provider.export(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + + InFileStreamProducer producer = romFsProvider.getStreamProducer(package2FileSystemEntry); + System2Provider providerStream = new System2Provider(producer, keyChainHolder); + providerStream.getIni1Provider().export(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + } + long calculateReferenceCRC32(Path refPackage2Path) throws Exception{ + byte[] refPackage2Bytes = Files.readAllBytes(refPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(refPackage2Bytes, 0, refPackage2Bytes.length); + return crc32.getValue(); + } + + void validateChecksums(Path myPackage2Path, long refPackage2Crc32) throws Exception{ + // Check CRC32 for package2 file only + byte[] myPackage2Bytes = Files.readAllBytes(myPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(myPackage2Bytes, 0, myPackage2Bytes.length); + long myPackage2Crc32 = crc32.getValue(); + Assertions.assertEquals(myPackage2Crc32, refPackage2Crc32); + } + + void validateSizes(Path a, Path b) throws Exception{ + Assertions.assertEquals(Files.size(a), Files.size(b)); + } +} diff --git a/src/test/java/libKonogonka/package2/KernelBinExtractTest.java b/src/test/java/libKonogonka/package2/KernelBinExtractTest.java new file mode 100644 index 0000000..1407988 --- /dev/null +++ b/src/test/java/libKonogonka/package2/KernelBinExtractTest.java @@ -0,0 +1,149 @@ +package libKonogonka.package2; + +import libKonogonka.Converter; +import libKonogonka.KeyChainHolder; +import libKonogonka.Tools.NCA.NCAProvider; +import libKonogonka.Tools.RomFs.FileSystemEntry; +import libKonogonka.Tools.RomFs.RomFsProvider; +import libKonogonka.Tools.other.System2.System2Provider; +import libKonogonka.ctraes.InFileStreamProducer; +import org.junit.jupiter.api.*; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.CRC32; + +/* ..::::::::::::::::::::: # 2 :::::::::::::::::::::.. +* This test validates Kernel.bin CRC32 equality and sizes match between reference values and +* 1. Kernel.bin extracted from 'package2' file +* 2. Kernel.bin extracted from NCA file via streams +* */ + +public class KernelBinExtractTest { + final String KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"prod.keys"; + final String XCI_HEADER_KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"xci_header_key.txt"; + + final String pathToFirmware = "FilesForTests"+File.separator+"Firmware 14.1.0"; + + private static KeyChainHolder keyChainHolder; + + final String referenceFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"FAT"; + final String referenceExFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"ExFAT"; + final String exportFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_FAT"+File.separator+getClass().getSimpleName(); + final String exportExFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_ExFAT"+File.separator+getClass().getSimpleName(); + + @DisplayName("Kernel.bin extract test") + @Test + void testSystem2() throws Exception{ + makeKeys(); + String[] ncaFileNames = collectNcaFileNames(); + List ncaProviders = makeNcaProviders(ncaFileNames); + + NCAProvider system2FatNcaProvider = null; + NCAProvider system2ExFatNcaProvider = null; + + for (NCAProvider ncaProvider : ncaProviders) { + String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); + if (titleId.equals("0100000000000819")) + system2FatNcaProvider = ncaProvider; + else if (titleId.equals("010000000000081b")) + system2ExFatNcaProvider = ncaProvider; + } + + Assertions.assertNotNull(system2FatNcaProvider); + Assertions.assertNotNull(system2ExFatNcaProvider); + + System.out.println("FAT " + system2FatNcaProvider.getFile().getName()); + System.out.println("ExFAT " + system2ExFatNcaProvider.getFile().getName()); + + Assertions.assertTrue(system2FatNcaProvider.getFile().getName().endsWith("1212c.nca")); + Assertions.assertTrue(system2ExFatNcaProvider.getFile().getName().endsWith("cc081.nca")); + + testExportedFiles(system2FatNcaProvider, exportFat, referenceFat); + testExportedFiles(system2ExFatNcaProvider, exportExFat, referenceExFat); + } + void makeKeys() throws Exception{ + String keyValue = new String(Files.readAllBytes(Paths.get(XCI_HEADER_KEYS_FILE_LOCATION))).trim(); + Assertions.assertNotEquals(0, keyValue.length()); + keyChainHolder = new KeyChainHolder(KEYS_FILE_LOCATION, keyValue); + } + String[] collectNcaFileNames(){ + File firmware = new File(pathToFirmware); + Assertions.assertTrue(firmware.exists()); + String[] ncaFileNames = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca"))); + Assertions.assertNotNull(ncaFileNames); + return ncaFileNames; + } + List makeNcaProviders(String[] ncaFileNames) throws Exception{ + List ncaProviders = new ArrayList<>(); + for (String ncaFileName : ncaFileNames){ + File nca = new File(pathToFirmware+File.separator+ncaFileName); + NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet()); + ncaProviders.add(provider); + } + + Assertions.assertNotEquals(0, ncaProviders.size()); + + return ncaProviders; + } + + void testExportedFiles(NCAProvider system2NcaProvider, String exportIntoFolder, String referenceFilesFolder) throws Exception{ + RomFsProvider romFsProvider = system2NcaProvider.getNCAContentProvider(0).getRomfs(); + + FileSystemEntry package2FileSystemEntry = romFsProvider.getRootEntry().getContent() + .stream() + .filter(e -> e.getName().equals("nx")) + .collect(Collectors.toList()) + .get(0) + .getContent() + .stream() + .filter(e -> e.getName().equals("package2")) + .collect(Collectors.toList()) + .get(0); + + Path referenceFilePath = Paths.get(referenceFilesFolder+File.separator+"package2"+File.separator+"Kernel.bin"); + Path myFilePath = Paths.get(exportIntoFolder+File.separator+"Kernel.bin"); + + System.out.println(); + System.out.println("Reference : " + referenceFilePath); + System.out.println("Own : " + myFilePath); + long referenceCrc32 = calculateReferenceCRC32(referenceFilePath); + + romFsProvider.exportContent(exportIntoFolder, package2FileSystemEntry); + System2Provider providerFile = new System2Provider(exportIntoFolder+File.separator+"package2", keyChainHolder); + providerFile.exportKernel(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + + InFileStreamProducer producer = romFsProvider.getStreamProducer(package2FileSystemEntry); + System2Provider providerStream = new System2Provider(producer, keyChainHolder); + providerStream.exportKernel(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + } + long calculateReferenceCRC32(Path refPackage2Path) throws Exception{ + byte[] refPackage2Bytes = Files.readAllBytes(refPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(refPackage2Bytes, 0, refPackage2Bytes.length); + return crc32.getValue(); + } + + void validateChecksums(Path myPackage2Path, long refPackage2Crc32) throws Exception{ + // Check CRC32 for package2 file only + byte[] myPackage2Bytes = Files.readAllBytes(myPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(myPackage2Bytes, 0, myPackage2Bytes.length); + long myPackage2Crc32 = crc32.getValue(); + Assertions.assertEquals(myPackage2Crc32, refPackage2Crc32); + } + + void validateSizes(Path a, Path b) throws Exception{ + Assertions.assertEquals(Files.size(a), Files.size(b)); + } +} diff --git a/src/test/java/libKonogonka/package2/Kip1ExtractTest.java b/src/test/java/libKonogonka/package2/Kip1ExtractTest.java new file mode 100644 index 0000000..d46081e --- /dev/null +++ b/src/test/java/libKonogonka/package2/Kip1ExtractTest.java @@ -0,0 +1,156 @@ +package libKonogonka.package2; + +import libKonogonka.Converter; +import libKonogonka.KeyChainHolder; +import libKonogonka.Tools.NCA.NCAProvider; +import libKonogonka.Tools.RomFs.FileSystemEntry; +import libKonogonka.Tools.RomFs.RomFsProvider; +import libKonogonka.Tools.other.System2.System2Provider; +import libKonogonka.Tools.other.System2.ini1.Ini1Provider; +import libKonogonka.Tools.other.System2.ini1.KIP1Provider; +import libKonogonka.ctraes.InFileStreamProducer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.CRC32; + +/* ..::::::::::::::::::::: # 4 :::::::::::::::::::::.. +* This test validates KIP1.bin CRC32 equality and sizes match between reference values and +* 1. KIP1.bin extracted from INI1.bin file +* 2. KIP1.bin extracted from NCA file via streams +* */ + +public class Kip1ExtractTest { + final String KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"prod.keys"; + final String XCI_HEADER_KEYS_FILE_LOCATION = "FilesForTests"+File.separator+"xci_header_key.txt"; + + final String pathToFirmware = "FilesForTests"+File.separator+"Firmware 14.1.0"; + + private static KeyChainHolder keyChainHolder; + + final String referenceFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"FAT"; + final String referenceExFat = "FilesForTests"+File.separator+"reference_for_system2"+File.separator+"ExFAT"; + final String exportFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_FAT"+File.separator+getClass().getSimpleName(); + final String exportExFat = System.getProperty("java.io.tmpdir")+File.separator+"Exported_ExFAT"+File.separator+getClass().getSimpleName(); + + @DisplayName("KIP1 extract test (case 'FS')") + @Test + void testSystem2() throws Exception{ + makeKeys(); + String[] ncaFileNames = collectNcaFileNames(); + List ncaProviders = makeNcaProviders(ncaFileNames); + + NCAProvider system2FatNcaProvider = null; + NCAProvider system2ExFatNcaProvider = null; + + for (NCAProvider ncaProvider : ncaProviders) { + String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId()); + if (titleId.equals("0100000000000819")) + system2FatNcaProvider = ncaProvider; + else if (titleId.equals("010000000000081b")) + system2ExFatNcaProvider = ncaProvider; + } + + Assertions.assertNotNull(system2FatNcaProvider); + Assertions.assertNotNull(system2ExFatNcaProvider); + + System.out.println("FAT " + system2FatNcaProvider.getFile().getName()); + System.out.println("ExFAT " + system2ExFatNcaProvider.getFile().getName()); + + Assertions.assertTrue(system2FatNcaProvider.getFile().getName().endsWith("1212c.nca")); + Assertions.assertTrue(system2ExFatNcaProvider.getFile().getName().endsWith("cc081.nca")); + + testExportedFiles(system2FatNcaProvider, exportFat, referenceFat); + testExportedFiles(system2ExFatNcaProvider, exportExFat, referenceExFat); + } + void makeKeys() throws Exception{ + String keyValue = new String(Files.readAllBytes(Paths.get(XCI_HEADER_KEYS_FILE_LOCATION))).trim(); + Assertions.assertNotEquals(0, keyValue.length()); + keyChainHolder = new KeyChainHolder(KEYS_FILE_LOCATION, keyValue); + } + String[] collectNcaFileNames(){ + File firmware = new File(pathToFirmware); + Assertions.assertTrue(firmware.exists()); + String[] ncaFileNames = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca"))); + Assertions.assertNotNull(ncaFileNames); + return ncaFileNames; + } + List makeNcaProviders(String[] ncaFileNames) throws Exception{ + List ncaProviders = new ArrayList<>(); + for (String ncaFileName : ncaFileNames){ + File nca = new File(pathToFirmware+File.separator+ncaFileName); + NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet()); + ncaProviders.add(provider); + } + + Assertions.assertNotEquals(0, ncaProviders.size()); + + return ncaProviders; + } + + void testExportedFiles(NCAProvider system2NcaProvider, String exportIntoFolder, String referenceFilesFolder) throws Exception{ + RomFsProvider romFsProvider = system2NcaProvider.getNCAContentProvider(0).getRomfs(); + + FileSystemEntry package2FileSystemEntry = romFsProvider.getRootEntry().getContent() + .stream() + .filter(e -> e.getName().equals("nx")) + .collect(Collectors.toList()) + .get(0) + .getContent() + .stream() + .filter(e -> e.getName().equals("package2")) + .collect(Collectors.toList()) + .get(0); + + Path referenceFilePath = Paths.get(referenceFilesFolder+File.separator+"ini1_extracted"+File.separator+"FS.kip1"); + Path myFilePath = Paths.get(exportIntoFolder+File.separator+"FS.kip1"); + + System.out.println(); + System.out.println("Reference : " + referenceFilePath); + System.out.println("Own : " + myFilePath); + long referenceCrc32 = calculateReferenceCRC32(referenceFilePath); + + romFsProvider.exportContent(exportIntoFolder, package2FileSystemEntry); + System2Provider kernelProviderFile = new System2Provider(exportIntoFolder+File.separator+"package2", keyChainHolder); + kernelProviderFile.getIni1Provider().export(exportIntoFolder); + Ini1Provider ini1Provider = new Ini1Provider(Paths.get(exportIntoFolder+File.separator+"INI1.bin")); + for (KIP1Provider kip1Provider : ini1Provider.getKip1List()) + kip1Provider.export(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + + InFileStreamProducer producer = romFsProvider.getStreamProducer(package2FileSystemEntry); + System2Provider providerStream = new System2Provider(producer, keyChainHolder); + for (KIP1Provider kip1Provider : providerStream.getIni1Provider().getKip1List()) + kip1Provider.export(exportIntoFolder); + validateChecksums(myFilePath, referenceCrc32); + validateSizes(referenceFilePath, myFilePath); + } + long calculateReferenceCRC32(Path refPackage2Path) throws Exception{ + byte[] refPackage2Bytes = Files.readAllBytes(refPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(refPackage2Bytes, 0, refPackage2Bytes.length); + return crc32.getValue(); + } + + void validateChecksums(Path myPackage2Path, long refPackage2Crc32) throws Exception{ + // Check CRC32 for package2 file only + byte[] myPackage2Bytes = Files.readAllBytes(myPackage2Path); + CRC32 crc32 = new CRC32(); + crc32.update(myPackage2Bytes, 0, myPackage2Bytes.length); + long myPackage2Crc32 = crc32.getValue(); + Assertions.assertEquals(myPackage2Crc32, refPackage2Crc32); + } + + void validateSizes(Path a, Path b) throws Exception{ + Assertions.assertEquals(Files.size(a), Files.size(b)); + } +} diff --git a/src/test/java/libKonogonka/RomFsDecrypted/ExportNso0FromNcaTest.java b/src/test/java/libKonogonka/unsorted/ExportNso0FromNcaTest.java similarity index 98% rename from src/test/java/libKonogonka/RomFsDecrypted/ExportNso0FromNcaTest.java rename to src/test/java/libKonogonka/unsorted/ExportNso0FromNcaTest.java index 080f7ee..ccff433 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/ExportNso0FromNcaTest.java +++ b/src/test/java/libKonogonka/unsorted/ExportNso0FromNcaTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.Tools.NCA.NCAProvider; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/KeyChainHolderTest.java b/src/test/java/libKonogonka/unsorted/KeyChainHolderTest.java similarity index 98% rename from src/test/java/libKonogonka/RomFsDecrypted/KeyChainHolderTest.java rename to src/test/java/libKonogonka/unsorted/KeyChainHolderTest.java index 97cb3dc..afc4b5b 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/KeyChainHolderTest.java +++ b/src/test/java/libKonogonka/unsorted/KeyChainHolderTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import org.junit.jupiter.api.Disabled; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/NCAProviderSimpleTest.java b/src/test/java/libKonogonka/unsorted/NCAProviderSimpleTest.java similarity index 98% rename from src/test/java/libKonogonka/RomFsDecrypted/NCAProviderSimpleTest.java rename to src/test/java/libKonogonka/unsorted/NCAProviderSimpleTest.java index e765a71..36377f5 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/NCAProviderSimpleTest.java +++ b/src/test/java/libKonogonka/unsorted/NCAProviderSimpleTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.Tools.NCA.NCAProvider; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/NSODecompressTest.java b/src/test/java/libKonogonka/unsorted/NSODecompressTest.java similarity index 97% rename from src/test/java/libKonogonka/RomFsDecrypted/NSODecompressTest.java rename to src/test/java/libKonogonka/unsorted/NSODecompressTest.java index 16b3931..7c50d66 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/NSODecompressTest.java +++ b/src/test/java/libKonogonka/unsorted/NSODecompressTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.Tools.NSO.NSO0Provider; import org.junit.jupiter.api.Disabled; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/NSOTest.java b/src/test/java/libKonogonka/unsorted/NSOTest.java similarity index 99% rename from src/test/java/libKonogonka/RomFsDecrypted/NSOTest.java rename to src/test/java/libKonogonka/unsorted/NSOTest.java index 05395d1..5c10d78 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/NSOTest.java +++ b/src/test/java/libKonogonka/unsorted/NSOTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.RainbowDump; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/NSPpfs0EncryptedTest.java b/src/test/java/libKonogonka/unsorted/NSPpfs0EncryptedTest.java similarity index 99% rename from src/test/java/libKonogonka/RomFsDecrypted/NSPpfs0EncryptedTest.java rename to src/test/java/libKonogonka/unsorted/NSPpfs0EncryptedTest.java index b9f3e04..527ac65 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/NSPpfs0EncryptedTest.java +++ b/src/test/java/libKonogonka/unsorted/NSPpfs0EncryptedTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.RainbowDump; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/PFS0Test.java b/src/test/java/libKonogonka/unsorted/PFS0Test.java similarity index 98% rename from src/test/java/libKonogonka/RomFsDecrypted/PFS0Test.java rename to src/test/java/libKonogonka/unsorted/PFS0Test.java index 2e89c51..9c76293 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/PFS0Test.java +++ b/src/test/java/libKonogonka/unsorted/PFS0Test.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.TitleKeyChainHolder; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/Pfs0EncryptedTest.java b/src/test/java/libKonogonka/unsorted/Pfs0EncryptedTest.java similarity index 99% rename from src/test/java/libKonogonka/RomFsDecrypted/Pfs0EncryptedTest.java rename to src/test/java/libKonogonka/unsorted/Pfs0EncryptedTest.java index dbe30cb..bf39269 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/Pfs0EncryptedTest.java +++ b/src/test/java/libKonogonka/unsorted/Pfs0EncryptedTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.RainbowDump; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/RomFsDecryptedTest.java b/src/test/java/libKonogonka/unsorted/RomFsDecryptedTest.java similarity index 99% rename from src/test/java/libKonogonka/RomFsDecrypted/RomFsDecryptedTest.java rename to src/test/java/libKonogonka/unsorted/RomFsDecryptedTest.java index e0d4e7f..2db5589 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/RomFsDecryptedTest.java +++ b/src/test/java/libKonogonka/unsorted/RomFsDecryptedTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import java.io.*; import java.nio.file.Files; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/RomFsEncryptedTest.java b/src/test/java/libKonogonka/unsorted/RomFsEncryptedTest.java similarity index 99% rename from src/test/java/libKonogonka/RomFsDecrypted/RomFsEncryptedTest.java rename to src/test/java/libKonogonka/unsorted/RomFsEncryptedTest.java index c427333..ebe4ece 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/RomFsEncryptedTest.java +++ b/src/test/java/libKonogonka/unsorted/RomFsEncryptedTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.ctraes.AesCtrBufferedInputStream; import libKonogonka.KeyChainHolder; diff --git a/src/test/java/libKonogonka/RomFsDecrypted/XciTest.java b/src/test/java/libKonogonka/unsorted/XciTest.java similarity index 98% rename from src/test/java/libKonogonka/RomFsDecrypted/XciTest.java rename to src/test/java/libKonogonka/unsorted/XciTest.java index 90fad08..5112640 100644 --- a/src/test/java/libKonogonka/RomFsDecrypted/XciTest.java +++ b/src/test/java/libKonogonka/unsorted/XciTest.java @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with libKonogonka. If not, see . */ -package libKonogonka.RomFsDecrypted; +package libKonogonka.unsorted; import libKonogonka.KeyChainHolder; import libKonogonka.Tools.NCA.NCAProvider;