From 8c75a1a43e81150e0bda674a1d32037870399099 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 11 Apr 2019 13:28:12 +0200 Subject: [PATCH] Move the decryption of a inputstream into a output stream in the NUSDecryption class. --- .../FSTDataProviderNUSTitle.java | 48 +++---------------- .../utils/cryptography/NUSDecryption.java | 43 +++++++++++++++++ 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java b/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java index bfa104f..f61b8fc 100644 --- a/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java +++ b/src/de/mas/wiiu/jnus/implementations/FSTDataProviderNUSTitle.java @@ -95,7 +95,12 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle { InputStream in = dataProvider.getInputStreamFromContent(c, fileOffsetBlock); try { - return decryptStreams(in, outputStream, fileSize, fileOffset, c); + NUSDecryption nusdecryption = new NUSDecryption(title.getTicket()); + Optional h3HashedOpt = Optional.empty(); + if (c.isHashed()) { + h3HashedOpt = dataProvider.getContentH3Hash(c); + } + return nusdecryption.decryptStreams(in, outputStream, fileSize, fileOffset, c, h3HashedOpt); } catch (CheckSumWrongException e) { if (entry.getContent().isUNKNWNFlag1Set()) { log.info("Hash doesn't match. But file is optional. Don't worry."); @@ -115,47 +120,6 @@ public class FSTDataProviderNUSTitle implements FSTDataProvider, HasNUSTitle { return false; } - private boolean decryptStreams(InputStream inputStream, OutputStream outputStream, long size, long offset, Content content) - throws IOException, CheckSumWrongException { - NUSDecryption nusdecryption = new NUSDecryption(title.getTicket()); - short contentIndex = (short) content.getIndex(); - - long encryptedFileSize = content.getEncryptedFileSize(); - - if (content.isEncrypted()) { - if (content.isHashed()) { - NUSDataProvider dataProvider = title.getDataProvider(); - byte[] h3 = dataProvider.getContentH3Hash(content).orElseThrow(() -> new FileNotFoundException("h3 hash not found.")); - - nusdecryption.decryptFileStreamHashed(inputStream, outputStream, size, offset, (short) contentIndex, h3); - } else { - try { - byte[] h3Hash = content.getSHA2Hash(); - // We want to check if we read the whole file or just a part of it. - // There should be only one actual file inside a non-hashed content. - // But it could also contain a directory, so we need to filter. - long fstFileSize = content.getEntries().stream().filter(f -> !f.isDir()).findFirst().map(f -> f.getFileSize()).orElse(0L); - if (size > 0 && size < fstFileSize) { - h3Hash = null; - } - nusdecryption.decryptFileStream(inputStream, outputStream, size, offset, (short) contentIndex, h3Hash, encryptedFileSize); - } catch (Exception e) { - e.printStackTrace(); - } - } - } else { - StreamUtils.saveInputStreamToOutputStreamWithHash(inputStream, outputStream, size, content.getSHA2Hash(), encryptedFileSize); - } - - synchronized (inputStream) { - inputStream.close(); - } - synchronized (outputStream) { - outputStream.close(); - } - return true; - } - @Override public NUSTitle getNUSTitle() { return title; diff --git a/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java b/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java index 8fec8fe..d7f7703 100644 --- a/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java +++ b/src/de/mas/wiiu/jnus/utils/cryptography/NUSDecryption.java @@ -16,6 +16,7 @@ ****************************************************************************/ package de.mas.wiiu.jnus.utils.cryptography; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -23,8 +24,10 @@ import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import java.util.Optional; import de.mas.wiiu.jnus.entities.Ticket; +import de.mas.wiiu.jnus.entities.content.Content; import de.mas.wiiu.jnus.utils.ByteArrayBuffer; import de.mas.wiiu.jnus.utils.CheckSumWrongException; import de.mas.wiiu.jnus.utils.HashUtil; @@ -263,4 +266,44 @@ public class NUSDecryption extends AESDecryption { return output; } + + public boolean decryptStreams(InputStream inputStream, OutputStream outputStream, long size, long offset, Content content, Optional h3HashHashed) + throws IOException, CheckSumWrongException { + + short contentIndex = (short) content.getIndex(); + + long encryptedFileSize = content.getEncryptedFileSize(); + + 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 { + try { + byte[] h3Hash = content.getSHA2Hash(); + // We want to check if we read the whole file or just a part of it. + // There should be only one actual file inside a non-hashed content. + // But it could also contain a directory, so we need to filter. + long fstFileSize = content.getEntries().stream().filter(f -> !f.isDir()).findFirst().map(f -> f.getFileSize()).orElse(0L); + if (size > 0 && size < fstFileSize) { + h3Hash = null; + } + decryptFileStream(inputStream, outputStream, size, offset, (short) contentIndex, h3Hash, encryptedFileSize); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + StreamUtils.saveInputStreamToOutputStreamWithHash(inputStream, outputStream, size, content.getSHA2Hash(), encryptedFileSize); + } + + synchronized (inputStream) { + inputStream.close(); + } + synchronized (outputStream) { + outputStream.close(); + } + return true; + } }