mirror of
https://github.com/Maschell/JNUSLib.git
synced 2024-10-02 00:35:08 +02:00
Throw proper exception while hashing
This commit is contained in:
parent
9f6f9aaabe
commit
59411e4c7d
@ -124,7 +124,12 @@ public final class WUDService {
|
|||||||
Integer oldOffset = null;
|
Integer oldOffset = null;
|
||||||
do {
|
do {
|
||||||
int read = StreamUtils.getChunkFromStream(in, blockBuffer, overflow, bufferSize);
|
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) {
|
if ((oldOffset = sectorHashes.get(hash)) == null) {
|
||||||
sectorMapping.put(curSector, realSector);
|
sectorMapping.put(curSector, realSector);
|
||||||
|
@ -20,6 +20,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -95,13 +96,13 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return decryptFSTEntryToStream(entry, out, fileOffsetBlock, fileOffset, usedSize);
|
return decryptFSTEntryToStream(entry, out, fileOffsetBlock, fileOffset, usedSize);
|
||||||
} catch (CheckSumWrongException e) {
|
} catch (CheckSumWrongException | NoSuchAlgorithmException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean decryptFSTEntryToStream(FSTEntry entry, OutputStream outputStream, long fileOffsetBlock, long fileOffset, long fileSize)
|
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 (entry.isNotInPackage() || !entry.getContent().isPresent() || !title.getTicket().isPresent()) {
|
||||||
if (!title.getTicket().isPresent()) {
|
if (!title.getTicket().isPresent()) {
|
||||||
log.info("Decryption not possible because no ticket was set.");
|
log.info("Decryption not possible because no ticket was set.");
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
package de.mas.wiiu.jnus.implementations.wud.parser;
|
package de.mas.wiiu.jnus.implementations.wud.parser;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
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);
|
byte[] hash = Arrays.copyOfRange(header, start_offset + offset * 0x14, start_offset + (offset + cnt_hashes) * 0x14);
|
||||||
|
|
||||||
// Checking the hash of the h3 file.
|
// Checking the hash of the h3 file.
|
||||||
if (!Arrays.equals(HashUtil.hashSHA1(hash), c.getSHA2Hash())) {
|
try {
|
||||||
log.info("h3 incorrect from WUD");
|
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);
|
addH3Hashes(c.getIndex(), hash);
|
||||||
|
@ -19,6 +19,7 @@ package de.mas.wiiu.jnus.utils;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -75,15 +76,20 @@ public class DataProviderUtils {
|
|||||||
File output = new File(outputFolder + File.separator + h3Filename);
|
File output = new File(outputFolder + File.separator + h3Filename);
|
||||||
|
|
||||||
if (output.exists()) {
|
if (output.exists()) {
|
||||||
if (Arrays.equals(content.getSHA2Hash(), HashUtil.hashSHA1(output))) {
|
try {
|
||||||
log.fine(h3Filename + " already exists");
|
if (Arrays.equals(content.getSHA2Hash(), HashUtil.hashSHA1(output))) {
|
||||||
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");
|
log.fine(h3Filename + " already exists");
|
||||||
return false;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,50 +68,31 @@ public final class HashUtil {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hashSHA1(byte[] data) {
|
public static byte[] hashSHA1(byte[] data) throws NoSuchAlgorithmException {
|
||||||
MessageDigest sha1;
|
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||||
try {
|
|
||||||
sha1 = MessageDigest.getInstance("SHA1");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return new byte[0x14];
|
|
||||||
}
|
|
||||||
|
|
||||||
return sha1.digest(data);
|
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);
|
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];
|
byte[] hash = new byte[0x14];
|
||||||
MessageDigest sha1 = null;
|
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||||
try {
|
hash = hash(sha1, in, length, 0x8000, aligmnent);
|
||||||
sha1 = MessageDigest.getInstance("SHA1");
|
|
||||||
hash = hash(sha1, in, length, 0x8000, aligmnent);
|
|
||||||
} catch (NoSuchAlgorithmException | FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hashSHA1(File file) {
|
public static byte[] hashSHA1(File file) throws NoSuchAlgorithmException, IOException {
|
||||||
return hashSHA1(file, 0);
|
return hashSHA1(file, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hashSHA1(File file, int aligmnent) {
|
public static byte[] hashSHA1(File file, int aligmnent) throws NoSuchAlgorithmException, IOException {
|
||||||
InputStream in;
|
InputStream in = new FileInputStream(file);
|
||||||
try {
|
return hashSHA1(in, file.length(), aligmnent);
|
||||||
in = new FileInputStream(file);
|
|
||||||
return hashSHA1(in, file.length(), aligmnent);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hash(MessageDigest digest, InputStream in, long inputSize1, int bufferSize, int alignment) throws IOException {
|
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();
|
return digest.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean compareHashFolder(File input1, File input2) {
|
public static boolean compareHashFolder(File input1, File input2) throws NoSuchAlgorithmException, IOException {
|
||||||
List<File> expectedFiles = getInputFilesForFolder(input1);
|
List<File> expectedFiles = getInputFilesForFolder(input1);
|
||||||
List<File> givenFiles = getInputFilesForFolder(input2);
|
List<File> givenFiles = getInputFilesForFolder(input2);
|
||||||
String regexInput = input1.getAbsolutePath().toLowerCase();
|
String regexInput = input1.getAbsolutePath().toLowerCase();
|
||||||
@ -193,7 +174,7 @@ public final class HashUtil {
|
|||||||
return result;
|
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()) {
|
if (file1 == null || !file1.exists() || file2 == null || !file2.exists()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -226,7 +207,7 @@ public final class HashUtil {
|
|||||||
return result;
|
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 H0_start = (block % 16) * 20;
|
||||||
int H1_start = (16 + (block / 16) % 16) * 20;
|
int H1_start = (16 + (block / 16) % 16) * 20;
|
||||||
int H2_start = (32 + (block / 256) % 16) * 20;
|
int H2_start = (32 + (block / 256) % 16) * 20;
|
||||||
@ -277,5 +258,6 @@ public final class HashUtil {
|
|||||||
log.finest("h3 checksum right!");
|
log.finest("h3 checksum right!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ public class NUSDecryption extends AESDecryption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void decryptFileStreamHashed(InputStream inputStream, OutputStream outputStream, long filesize, long fileoffset, short contentIndex, byte[] h3Hash)
|
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 BLOCKSIZE = 0x10000;
|
||||||
int HASHBLOCKSIZE = 0xFC00;
|
int HASHBLOCKSIZE = 0xFC00;
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ public class NUSDecryption extends AESDecryption {
|
|||||||
byte[] output;
|
byte[] output;
|
||||||
try {
|
try {
|
||||||
output = decryptFileChunkHash(encryptedBlockBuffer, (int) block, contentIndex, h3Hash);
|
output = decryptFileChunkHash(encryptedBlockBuffer, (int) block, contentIndex, h3Hash);
|
||||||
} catch (CheckSumWrongException e) {
|
} catch (CheckSumWrongException | NoSuchAlgorithmException e) {
|
||||||
throw 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 hashSize = 0x400;
|
||||||
int blocksize = 0xFC00;
|
int blocksize = 0xFC00;
|
||||||
byte[] IV = ByteBuffer.allocate(16).putShort((short) contentIndex).array();
|
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<byte[]> h3HashHashed)
|
public boolean decryptStreams(InputStream inputStream, OutputStream outputStream, long size, long offset, Content content, Optional<byte[]> h3HashHashed)
|
||||||
throws IOException, CheckSumWrongException {
|
throws IOException, CheckSumWrongException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
short contentIndex = (short) content.getIndex();
|
short contentIndex = (short) content.getIndex();
|
||||||
|
|
||||||
@ -278,7 +279,6 @@ public class NUSDecryption extends AESDecryption {
|
|||||||
if (content.isEncrypted()) {
|
if (content.isEncrypted()) {
|
||||||
if (content.isHashed()) {
|
if (content.isHashed()) {
|
||||||
byte[] h3 = h3HashHashed.orElseThrow(() -> new FileNotFoundException("h3 hash not found."));
|
byte[] h3 = h3HashHashed.orElseThrow(() -> new FileNotFoundException("h3 hash not found."));
|
||||||
|
|
||||||
decryptFileStreamHashed(inputStream, outputStream, size, offset, (short) contentIndex, h3);
|
decryptFileStreamHashed(inputStream, outputStream, size, offset, (short) contentIndex, h3);
|
||||||
} else {
|
} else {
|
||||||
byte[] h3Hash = content.getSHA2Hash();
|
byte[] h3Hash = content.getSHA2Hash();
|
||||||
|
Loading…
Reference in New Issue
Block a user