Added cert downloading for remote titles

This commit is contained in:
Maschell 2017-07-28 16:53:52 +02:00
parent 2f30ab6e0c
commit 0dc62ef4c0
3 changed files with 83 additions and 8 deletions

View File

@ -4,7 +4,9 @@ import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.mas.wiiu.jnus.entities.content.Content;
@ -29,6 +31,11 @@ public final class TMD {
private static final int CONTENT_INFO_OFFSET = 0x204;
private static final int CONTENT_OFFSET = 0xB04;
private static final int CERT1_LENGTH = 0x400;
private static final int CERT2_LENGTH = 0x300;
@Getter private final int signatureType; // 0x000
@Getter private final byte[] signature; // 0x004
@ -47,6 +54,9 @@ public final class TMD {
@Getter private final short bootIndex; // 0x1E0
@Getter private final byte[] SHA2; // 0x1E4
@Getter private final ContentInfo[] contentInfos;
@Getter private byte[] cert1;
@Getter private byte[] cert2;
private final Map<Integer, Content> contentToIndex = new HashMap<>();
private final Map<Integer, Content> contentToID = new HashMap<>();
@ -69,6 +79,8 @@ public final class TMD {
this.bootIndex = param.getBootIndex();
this.SHA2 = param.getSHA2();
this.contentInfos = param.getContentInfos();
this.cert1 = param.getCert1();
this.cert2 = param.getCert2();
}
public static TMD parseTMD(File tmd) throws IOException {
@ -84,6 +96,8 @@ public final class TMD {
byte[] issuer = new byte[ISSUER_LENGTH];
byte[] reserved = new byte[RESERVED_LENGTH];
byte[] SHA2 = new byte[SHA2_LENGTH];
byte[] cert1 = new byte[CERT1_LENGTH];
byte[] cert2 = new byte[CERT2_LENGTH];
ContentInfo[] contentInfos = new ContentInfo[CONTENT_INFO_ARRAY_SIZE];
@ -136,6 +150,28 @@ public final class TMD {
contentInfos[i] = ContentInfo.parseContentInfo(contentInfo);
}
List<Content> contentList = new ArrayList<>();
// Get Contents
for (int i = 0; i < contentCount; i++) {
buffer.position(CONTENT_OFFSET + (Content.CONTENT_SIZE * i));
byte[] content = new byte[Content.CONTENT_SIZE];
buffer.get(content, 0, Content.CONTENT_SIZE);
Content c = Content.parseContent(content);
contentList.add(c);
}
try{
buffer.get(cert2, 0, CERT2_LENGTH);
}catch(Exception e){
}
try{
buffer.get(cert1, 0, CERT1_LENGTH);
}catch(Exception e){
}
TMDParam param = new TMDParam();
param.setSignatureType(signatureType);
param.setSignature(signature);
@ -152,15 +188,12 @@ public final class TMD {
param.setBootIndex(bootIndex);
param.setSHA2(SHA2);
param.setContentInfos(contentInfos);
param.setCert1(cert1);
param.setCert2(cert2);
TMD result = new TMD(param);
// Get Contents
for (int i = 0; i < contentCount; i++) {
buffer.position(CONTENT_OFFSET + (Content.CONTENT_SIZE * i));
byte[] content = new byte[Content.CONTENT_SIZE];
buffer.get(content, 0, Content.CONTENT_SIZE);
Content c = Content.parseContent(content);
for(Content c : contentList){
result.setContentToIndex(c.getIndex(), c);
result.setContentToID(c.getID(), c);
}
@ -222,5 +255,7 @@ public final class TMD {
private short bootIndex; // 0x1E0
private byte[] SHA2; // 0x1E4
private ContentInfo[] contentInfos; //
private byte[] cert1;
private byte[] cert2;
}
}

View File

@ -1,9 +1,14 @@
package de.mas.wiiu.jnus.implementations;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;
import de.mas.wiiu.jnus.NUSTitle;
import de.mas.wiiu.jnus.Settings;
import de.mas.wiiu.jnus.entities.TMD;
import de.mas.wiiu.jnus.entities.content.Content;
import de.mas.wiiu.jnus.utils.download.NUSDownloadService;
import lombok.Getter;
@ -56,7 +61,22 @@ public class NUSDataProviderRemote extends NUSDataProvider {
@Override
public byte[] getRawCert() throws IOException {
return new byte[0]; // TODO: needs to be implemented
NUSDownloadService downloadService = NUSDownloadService.getDefaultInstance();
byte[] defaultCert = downloadService.downloadDefaultCertToByteArray();
TMD tmd = getNUSTitle().getTMD();
byte[] result = new byte[0];
try{
ByteArrayOutputStream fos = new ByteArrayOutputStream();
fos.write(tmd.getCert1());
fos.write(tmd.getCert2());
fos.write(defaultCert);
result = fos.toByteArray();
fos.close();
}catch(Exception e){
e.printStackTrace();
}
return result;
}
@Override

View File

@ -1,9 +1,12 @@
package de.mas.wiiu.jnus.utils.download;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -14,6 +17,8 @@ public final class NUSDownloadService extends Downloader {
private static Map<String, NUSDownloadService> instances = new HashMap<>();
private final String URL_BASE;
private byte[] defaultCertTicket = null;
private NUSDownloadService(String URL) {
this.URL_BASE = URL;
@ -30,6 +35,14 @@ public final class NUSDownloadService extends Downloader {
}
return instances.get(URL);
}
public byte[] getDefaultCert() throws IOException {
if(defaultCertTicket == null){
byte [] ticket = downloadTicketToByteArray(0x000500101000400AL); //Downloading cetk from OSv10
defaultCertTicket = Arrays.copyOfRange(ticket, 0x350, 0x350+0x300);
}
return defaultCertTicket;
}
public byte[] downloadTMDToByteArray(long titleID, int version) throws IOException {
String version_suf = "";
@ -37,6 +50,13 @@ public final class NUSDownloadService extends Downloader {
String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/tmd" + version_suf;
return downloadFileToByteArray(URL);
}
/**
* For the cert we need a part from a ticket. For this we simply load a public ticket and use it.
*/
public byte[] downloadDefaultCertToByteArray() throws IOException {
return getDefaultCert();
}
public byte[] downloadTicketToByteArray(long titleID) throws IOException {
String URL = URL_BASE + "/" + String.format("%016X", titleID) + "/cetk";