From 59411e4c7d4aa3c3691c8c5c3f4c0bcbd4d4c04f Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 19 Apr 2019 14:47:39 +0200 Subject: [PATCH] Throw proper exception while hashing --- src/de/mas/wiiu/jnus/WUDService.java | 7 ++- .../FSTDataProviderNUSTitle.java | 5 +- .../wud/parser/WUDPartitionHeader.java | 9 +++- .../wiiu/jnus/utils/DataProviderUtils.java | 18 +++++--- src/de/mas/wiiu/jnus/utils/HashUtil.java | 46 ++++++------------- .../utils/cryptography/NUSDecryption.java | 10 ++-- 6 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/de/mas/wiiu/jnus/WUDService.java b/src/de/mas/wiiu/jnus/WUDService.java index 6ecd8fe..eb8e29a 100644 --- a/src/de/mas/wiiu/jnus/WUDService.java +++ b/src/de/mas/wiiu/jnus/WUDService.java @@ -124,7 +124,12 @@ public final class WUDService { Integer oldOffset = null; do { int read = StreamUtils.getChunkFromStream(in, blockBuffer, overflow, bufferSize); - ByteArrayWrapper hash = new ByteArrayWrapper(HashUtil.hashSHA1(blockBuffer)); + ByteArrayWrapper hash; + try { + hash = new ByteArrayWrapper(HashUtil.hashSHA1(blockBuffer)); + } catch (NoSuchAlgorithmException e1) { + throw new IOException(e1); + } if ((oldOffset = sectorHashes.get(hash)) == null) { sectorMapping.put(curSector, realSector); diff --git a/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java b/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java index c4f8652..b9a8e80 100644 --- a/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java +++ b/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java @@ -20,6 +20,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.security.NoSuchAlgorithmException; import java.util.Optional; import java.util.stream.Collectors; @@ -95,13 +96,13 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle { } try { return decryptFSTEntryToStream(entry, out, fileOffsetBlock, fileOffset, usedSize); - } catch (CheckSumWrongException e) { + } catch (CheckSumWrongException | NoSuchAlgorithmException e) { throw new IOException(e); } } private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long fileOffsetBlock, long fileOffset, long fileSize) - throws IOException, CheckSumWrongException { + throws IOException, CheckSumWrongException, NoSuchAlgorithmException { if (entry.isNotInPackage() || !entry.getContent().isPresent() || !title.getTicket().isPresent()) { if (!title.getTicket().isPresent()) { log.info("Decryption not possible because no ticket was set."); diff --git a/src/de/mas/wiiu/jnus/implementations/wud/parser/WUDPartitionHeader.java b/src/de/mas/wiiu/jnus/implementations/wud/parser/WUDPartitionHeader.java index 46094b6..578e9f8 100644 --- a/src/de/mas/wiiu/jnus/implementations/wud/parser/WUDPartitionHeader.java +++ b/src/de/mas/wiiu/jnus/implementations/wud/parser/WUDPartitionHeader.java @@ -16,6 +16,7 @@ ****************************************************************************/ package de.mas.wiiu.jnus.implementations.wud.parser; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -85,8 +86,12 @@ public final class WUDPartitionHeader { byte[] hash = Arrays.copyOfRange(header, start_offset + offset * 0x14, start_offset + (offset + cnt_hashes) * 0x14); // Checking the hash of the h3 file. - if (!Arrays.equals(HashUtil.hashSHA1(hash), c.getSHA2Hash())) { - log.info("h3 incorrect from WUD"); + try { + if (!Arrays.equals(HashUtil.hashSHA1(hash), c.getSHA2Hash())) { + log.info("h3 incorrect from WUD"); + } + } catch (NoSuchAlgorithmException e) { + log.warning(e.getMessage()); } addH3Hashes(c.getIndex(), hash); diff --git a/src/de/mas/wiiu/jnus/utils/DataProviderUtils.java b/src/de/mas/wiiu/jnus/utils/DataProviderUtils.java index c6509e7..5818afa 100644 --- a/src/de/mas/wiiu/jnus/utils/DataProviderUtils.java +++ b/src/de/mas/wiiu/jnus/utils/DataProviderUtils.java @@ -19,6 +19,7 @@ package de.mas.wiiu.jnus.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Optional; @@ -75,15 +76,20 @@ public class DataProviderUtils { File output = new File(outputFolder + File.separator + h3Filename); if (output.exists()) { - if (Arrays.equals(content.getSHA2Hash(), HashUtil.hashSHA1(output))) { - log.fine(h3Filename + " already exists"); - return false; - } else { - if (Arrays.equals(content.getSHA2Hash(), Arrays.copyOf(HashUtil.hashSHA256(output), 20))) { // 0005000c1f941200 used sha256 instead of SHA1 + try { + if (Arrays.equals(content.getSHA2Hash(), HashUtil.hashSHA1(output))) { log.fine(h3Filename + " already exists"); return false; + } else { + if (Arrays.equals(content.getSHA2Hash(), Arrays.copyOf(HashUtil.hashSHA256(output), 20))) { // 0005000c1f941200 used sha256 instead of SHA1 + log.fine(h3Filename + " already exists"); + return false; + } + log.warning(h3Filename + " already exists but hash is differrent than expected."); } - log.warning(h3Filename + " already exists but hash is differrent than expected."); + } catch (NoSuchAlgorithmException e) { + log.warning(e.getMessage()); + return false; } } diff --git a/src/de/mas/wiiu/jnus/utils/HashUtil.java b/src/de/mas/wiiu/jnus/utils/HashUtil.java index 8b8b06b..474136f 100644 --- a/src/de/mas/wiiu/jnus/utils/HashUtil.java +++ b/src/de/mas/wiiu/jnus/utils/HashUtil.java @@ -68,50 +68,31 @@ public final class HashUtil { return hash; } - public static byte[] hashSHA1(byte[] data) { - MessageDigest sha1; - try { - sha1 = MessageDigest.getInstance("SHA1"); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return new byte[0x14]; - } + public static byte[] hashSHA1(byte[] data) throws NoSuchAlgorithmException { + MessageDigest sha1 = MessageDigest.getInstance("SHA1"); return sha1.digest(data); } - public static byte[] hashSHA1(InputStream in, long length) { + public static byte[] hashSHA1(InputStream in, long length) throws NoSuchAlgorithmException, IOException { return hashSHA1(in, length, 0); } - public static byte[] hashSHA1(InputStream in, long length, int aligmnent) { + public static byte[] hashSHA1(InputStream in, long length, int aligmnent) throws IOException, NoSuchAlgorithmException { byte[] hash = new byte[0x14]; - MessageDigest sha1 = null; - try { - sha1 = MessageDigest.getInstance("SHA1"); - hash = hash(sha1, in, length, 0x8000, aligmnent); - } catch (NoSuchAlgorithmException | FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + MessageDigest sha1 = MessageDigest.getInstance("SHA1"); + hash = hash(sha1, in, length, 0x8000, aligmnent); return hash; } - public static byte[] hashSHA1(File file) { + public static byte[] hashSHA1(File file) throws NoSuchAlgorithmException, IOException { return hashSHA1(file, 0); } - public static byte[] hashSHA1(File file, int aligmnent) { - InputStream in; - try { - in = new FileInputStream(file); - return hashSHA1(in, file.length(), aligmnent); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return null; + public static byte[] hashSHA1(File file, int aligmnent) throws NoSuchAlgorithmException, IOException { + InputStream in = new FileInputStream(file); + return hashSHA1(in, file.length(), aligmnent); } public static byte[] hash(MessageDigest digest, InputStream in, long inputSize1, int bufferSize, int alignment) throws IOException { @@ -142,7 +123,7 @@ public final class HashUtil { return digest.digest(); } - public static boolean compareHashFolder(File input1, File input2) { + public static boolean compareHashFolder(File input1, File input2) throws NoSuchAlgorithmException, IOException { List expectedFiles = getInputFilesForFolder(input1); List givenFiles = getInputFilesForFolder(input2); String regexInput = input1.getAbsolutePath().toLowerCase(); @@ -193,7 +174,7 @@ public final class HashUtil { return result; } - private static boolean compareHashFile(File file1, File file2) { + private static boolean compareHashFile(File file1, File file2) throws NoSuchAlgorithmException, IOException { if (file1 == null || !file1.exists() || file2 == null || !file2.exists()) { return false; } @@ -226,7 +207,7 @@ public final class HashUtil { return result; } - public static void checkFileChunkHashes(byte[] hashes, byte[] h3Hashes, byte[] output, int block) throws CheckSumWrongException { + public static void checkFileChunkHashes(byte[] hashes, byte[] h3Hashes, byte[] output, int block) throws CheckSumWrongException, NoSuchAlgorithmException { int H0_start = (block % 16) * 20; int H1_start = (16 + (block / 16) % 16) * 20; int H2_start = (32 + (block / 256) % 16) * 20; @@ -277,5 +258,6 @@ public final class HashUtil { log.finest("h3 checksum right!"); } } + } } diff --git a/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java b/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java index f8b86de..c8b46d2 100644 --- a/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java +++ b/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java @@ -192,7 +192,7 @@ public class NUSDecryption extends AESDecryption { } public void decryptFileStreamHashed(InputStream inputStream, OutputStream outputStream, long filesize, long fileoffset, short contentIndex, byte[] h3Hash) - throws IOException, CheckSumWrongException { + throws IOException, CheckSumWrongException, NoSuchAlgorithmException { int BLOCKSIZE = 0x10000; int HASHBLOCKSIZE = 0xFC00; @@ -215,7 +215,7 @@ public class NUSDecryption extends AESDecryption { byte[] output; try { output = decryptFileChunkHash(encryptedBlockBuffer, (int) block, contentIndex, h3Hash); - } catch (CheckSumWrongException e) { + } catch (CheckSumWrongException | NoSuchAlgorithmException e) { throw e; } @@ -247,7 +247,8 @@ public class NUSDecryption extends AESDecryption { } } - private byte[] decryptFileChunkHash(byte[] blockBuffer, int block, int contentIndex, byte[] h3_hashes) throws CheckSumWrongException { + private byte[] decryptFileChunkHash(byte[] blockBuffer, int block, int contentIndex, byte[] h3_hashes) + throws CheckSumWrongException, NoSuchAlgorithmException { int hashSize = 0x400; int blocksize = 0xFC00; byte[] IV = ByteBuffer.allocate(16).putShort((short) contentIndex).array(); @@ -268,7 +269,7 @@ public class NUSDecryption extends AESDecryption { } public boolean decryptStreams(InputStream inputStream, OutputStream outputStream, long size, long offset, Content content, Optional h3HashHashed) - throws IOException, CheckSumWrongException { + throws IOException, CheckSumWrongException, NoSuchAlgorithmException { short contentIndex = (short) content.getIndex(); @@ -278,7 +279,6 @@ public class NUSDecryption extends AESDecryption { if (content.isEncrypted()) { if (content.isHashed()) { byte[] h3 = h3HashHashed.orElseThrow(() -> new FileNotFoundException("h3 hash not found.")); - decryptFileStreamHashed(inputStream, outputStream, size, offset, (short) contentIndex, h3); } else { byte[] h3Hash = content.getSHA2Hash();