mirror of
https://github.com/WiiDatabase/nusdownloader.git
synced 2024-11-27 04:34:14 +01:00
Certs are now passively obtained. No more cert.sys needed
This commit is contained in:
parent
1624f99973
commit
c279b57136
23
NUS Downloader/Form1.Designer.cs
generated
23
NUS Downloader/Form1.Designer.cs
generated
@ -42,7 +42,6 @@
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.getcerts = new System.Windows.Forms.Button();
|
||||
this.wadnamebox = new System.Windows.Forms.TextBox();
|
||||
this.ignoreticket = new System.Windows.Forms.CheckBox();
|
||||
this.decryptbox = new System.Windows.Forms.CheckBox();
|
||||
@ -245,18 +244,6 @@
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// getcerts
|
||||
//
|
||||
this.getcerts.BackColor = System.Drawing.Color.Bisque;
|
||||
this.getcerts.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
|
||||
this.getcerts.Location = new System.Drawing.Point(48, 246);
|
||||
this.getcerts.Name = "getcerts";
|
||||
this.getcerts.Size = new System.Drawing.Size(176, 46);
|
||||
this.getcerts.TabIndex = 16;
|
||||
this.getcerts.Text = "Generate Certs";
|
||||
this.getcerts.UseVisualStyleBackColor = false;
|
||||
this.getcerts.Click += new System.EventHandler(this.getcerts_Click);
|
||||
//
|
||||
// wadnamebox
|
||||
//
|
||||
this.wadnamebox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
@ -757,9 +744,9 @@
|
||||
this.contentModBox.Controls.Add(this.button11);
|
||||
this.contentModBox.Controls.Add(this.button9);
|
||||
this.contentModBox.Controls.Add(this.button10);
|
||||
this.contentModBox.Location = new System.Drawing.Point(268, 153);
|
||||
this.contentModBox.Location = new System.Drawing.Point(278, 434);
|
||||
this.contentModBox.Name = "contentModBox";
|
||||
this.contentModBox.Size = new System.Drawing.Size(249, 327);
|
||||
this.contentModBox.Size = new System.Drawing.Size(249, 69);
|
||||
this.contentModBox.TabIndex = 41;
|
||||
this.contentModBox.TabStop = false;
|
||||
this.contentModBox.Text = "Edit Title Contents";
|
||||
@ -907,7 +894,7 @@
|
||||
this.toolStripSeparator3,
|
||||
this.emulateUpdate});
|
||||
this.extrasStrip.Name = "extrasStrip";
|
||||
this.extrasStrip.Size = new System.Drawing.Size(220, 76);
|
||||
this.extrasStrip.Size = new System.Drawing.Size(220, 54);
|
||||
//
|
||||
// loadInfoFromTMDToolStripMenuItem
|
||||
//
|
||||
@ -965,18 +952,17 @@
|
||||
this.Controls.Add(this.button3);
|
||||
this.Controls.Add(this.shamelessvariablelabel);
|
||||
this.Controls.Add(this.button1);
|
||||
this.Controls.Add(this.contentModBox);
|
||||
this.Controls.Add(this.button17);
|
||||
this.Controls.Add(this.ticketgpbox);
|
||||
this.Controls.Add(this.tmdgpbox);
|
||||
this.Controls.Add(this.truchabox);
|
||||
this.Controls.Add(this.databaseButton);
|
||||
this.Controls.Add(this.button5);
|
||||
this.Controls.Add(this.contentModBox);
|
||||
this.Controls.Add(this.button4);
|
||||
this.Controls.Add(this.decryptbox);
|
||||
this.Controls.Add(this.ignoreticket);
|
||||
this.Controls.Add(this.wadnamebox);
|
||||
this.Controls.Add(this.getcerts);
|
||||
this.Controls.Add(this.button7);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.titleversion);
|
||||
@ -1028,7 +1014,6 @@
|
||||
private System.Windows.Forms.RadioButton radioButton1;
|
||||
private System.Windows.Forms.RadioButton radioButton2;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.Button getcerts;
|
||||
private System.Windows.Forms.TextBox wadnamebox;
|
||||
private System.Windows.Forms.CheckBox ignoreticket;
|
||||
private System.Windows.Forms.CheckBox decryptbox;
|
||||
|
@ -31,6 +31,17 @@ namespace NUS_Downloader
|
||||
Image redgreen = Properties.Resources.bullet_redgreen;
|
||||
Image redorange = Properties.Resources.bullet_redorange;
|
||||
|
||||
// Certs storage
|
||||
byte[] cert_CA = new byte[0x400];
|
||||
byte[] cert_CACP = new byte[0x300];
|
||||
byte[] cert_CAXS = new byte[0x300];
|
||||
|
||||
byte[] cert_CA_sha1 = new byte[20] {0x5B, 0x7D, 0x3E, 0xE2, 0x87, 0x06, 0xAD, 0x8D, 0xA2, 0xCB, 0xD5, 0xA6, 0xB7, 0x5C, 0x15, 0xD0, 0xF9, 0xB6, 0xF3, 0x18};
|
||||
byte[] cert_CACP_sha1 = new byte[20] {0x68, 0x24, 0xD6, 0xDA, 0x4C, 0x25, 0x18, 0x4F, 0x0D, 0x6D, 0xAF, 0x6E, 0xDB, 0x9C, 0x0F, 0xC5, 0x75, 0x22, 0xA4, 0x1C};
|
||||
byte[] cert_CAXS_sha1 = new byte[20] {0x09, 0x78, 0x70, 0x45, 0x03, 0x71, 0x21, 0x47, 0x78, 0x24, 0xBC, 0x6A, 0x3E, 0x5E, 0x07, 0x61, 0x56, 0x57, 0x3F, 0x8A};
|
||||
|
||||
byte[] cert_total_sha1 = new byte[20] {0xAC, 0xE0, 0xF1, 0x5D, 0x2A, 0x85, 0x1C, 0x38, 0x3F, 0xE4, 0x65, 0x7A, 0xFC, 0x38, 0x40, 0xD6, 0xFF, 0xE3, 0x0A, 0xD0};
|
||||
|
||||
public struct WADHeader
|
||||
{
|
||||
public int HeaderSize;
|
||||
@ -67,6 +78,7 @@ namespace NUS_Downloader
|
||||
public Form1(string[] args)
|
||||
{
|
||||
InitializeComponent();
|
||||
Application.DoEvents();
|
||||
|
||||
// certs.sys / key.bin
|
||||
if (BootChecks() == false)
|
||||
@ -144,8 +156,8 @@ namespace NUS_Downloader
|
||||
|
||||
// Close if specified
|
||||
while (NUSDownloader.IsBusy)
|
||||
{
|
||||
// Do nothing...
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
if ((NUSDownloader.IsBusy == false) && (endafter == true))
|
||||
{
|
||||
@ -169,7 +181,7 @@ namespace NUS_Downloader
|
||||
if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
|
||||
currentdir += Path.DirectorySeparatorChar;
|
||||
|
||||
// Check for certs file
|
||||
/* Check for certs file
|
||||
if (File.Exists(currentdir + "cert.sys") == false)
|
||||
{
|
||||
foreach (Control ctrl in this.Controls)
|
||||
@ -194,7 +206,7 @@ namespace NUS_Downloader
|
||||
{
|
||||
getcerts.Visible = false;
|
||||
WriteStatus("Certs file is present and intact.");
|
||||
}
|
||||
}*/
|
||||
|
||||
// Check for Wii common key bin file...
|
||||
if (File.Exists(currentdir + "key.bin") == false)
|
||||
@ -728,13 +740,13 @@ namespace NUS_Downloader
|
||||
downloadstartbtn.Text = "Prerequisites: (2/2)";
|
||||
dlprogress.Value = 100;
|
||||
|
||||
// Create ticket file holder
|
||||
byte[] cetkbuf = FileLocationToByteArray(titledirectory + @"\cetk");
|
||||
|
||||
// Obtain TitleKey
|
||||
byte[] titlekey = new byte[16];
|
||||
if (decryptbox.Checked == true)
|
||||
{
|
||||
// Create ticket file holder
|
||||
byte[] cetkbuf = FileLocationToByteArray(titledirectory + @"\cetk");
|
||||
|
||||
// Load TitleKey into it's byte[]
|
||||
// It is currently encrypted...
|
||||
for (int i = 0; i < 16; i++)
|
||||
@ -778,6 +790,17 @@ namespace NUS_Downloader
|
||||
// Read the tmd as a stream...
|
||||
byte[] tmd = FileLocationToByteArray(titledirectory + tmdfull);
|
||||
|
||||
// Locate Certs **************************************
|
||||
if (!(CertsValid()))
|
||||
{
|
||||
WriteStatus("Searching for certs...");
|
||||
ScanForCerts(tmd);
|
||||
ScanForCerts(cetkbuf);
|
||||
}
|
||||
else
|
||||
WriteStatus("Using cached certs...");
|
||||
// /Locate Cert **************************************
|
||||
|
||||
// Read Title Version...
|
||||
string tmdversion = "";
|
||||
for (int x = 476; x < 478; x++)
|
||||
@ -859,9 +882,6 @@ namespace NUS_Downloader
|
||||
// Create content file holder
|
||||
byte[] contbuf = FileLocationToByteArray(titledirectory + @"\" + tmdcontents[i]);
|
||||
|
||||
// Create ticket file holder
|
||||
byte[] cetkbuf = FileLocationToByteArray(titledirectory + @"\cetk");
|
||||
|
||||
// IV (00+IDX+more000)
|
||||
byte[] iv = new byte[16];
|
||||
for (int x = 0; x < 16; x++)
|
||||
@ -927,13 +947,10 @@ namespace NUS_Downloader
|
||||
requiredIOSbox.Enabled = true;
|
||||
|
||||
// Read information from TIK into signing GUI...
|
||||
// Create ticket file holder
|
||||
byte[] cetkbuff = FileLocationToByteArray(titledirectory + @"\cetk");
|
||||
|
||||
// Titlekey
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
titlekey[i] = cetkbuff[0x1BF + i];
|
||||
titlekey[i] = cetkbuf[0x1BF + i];
|
||||
}
|
||||
//titlekeybox.Text = DisplayBytes(titlekey).Replace(" ", "");
|
||||
titlekeybox.Text = System.Text.Encoding.UTF7.GetString(titlekey);
|
||||
@ -942,7 +959,7 @@ namespace NUS_Downloader
|
||||
byte[] iv = new byte[16];
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
iv[i] = cetkbuff[0x1DC + i];
|
||||
iv[i] = cetkbuf[0x1DC + i];
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
@ -951,20 +968,20 @@ namespace NUS_Downloader
|
||||
titleIDIV.Text = DisplayBytes(iv, "");
|
||||
|
||||
//DLC
|
||||
dlcamntbox.Text = Convert.ToString((cetkbuff[0x1E6]*256) + cetkbuff[0x1E7]);
|
||||
dlcamntbox.Text = Convert.ToString((cetkbuf[0x1E6]*256) + cetkbuf[0x1E7]);
|
||||
|
||||
//keyindex
|
||||
if (cetkbuff[0x1F1] == 0x00)
|
||||
if (cetkbuf[0x1F1] == 0x00)
|
||||
ckeyindexcb.SelectedIndex = 0;
|
||||
else if (cetkbuff[0x1F1] == 0x01)
|
||||
else if (cetkbuf[0x1F1] == 0x01)
|
||||
ckeyindexcb.SelectedIndex = 1;
|
||||
else
|
||||
ckeyindexcb.SelectedIndex = 0;
|
||||
|
||||
//time enabled
|
||||
if (cetkbuff[0x247] == 0x00)
|
||||
if (cetkbuf[0x247] == 0x00)
|
||||
timelimitenabledcb.SelectedIndex = 0;
|
||||
else if (cetkbuff[0x247] == 0x01)
|
||||
else if (cetkbuf[0x247] == 0x01)
|
||||
timelimitenabledcb.SelectedIndex = 1;
|
||||
else
|
||||
timelimitenabledcb.SelectedIndex = 0;
|
||||
@ -973,7 +990,7 @@ namespace NUS_Downloader
|
||||
byte[] timelimit = new byte[4];
|
||||
for (int i = 0; i < timelimit.Length; i++)
|
||||
{
|
||||
timelimit[i] = cetkbuff[0x248 + 1];
|
||||
timelimit[i] = cetkbuf[0x248 + 1];
|
||||
}
|
||||
timelimitsecs.Text = Convert.ToString(System.BitConverter.ToInt32(timelimit, 0));
|
||||
|
||||
@ -1103,13 +1120,37 @@ namespace NUS_Downloader
|
||||
|
||||
public void PackWAD(string titleid, string tmdfilename, int contentcount, string[] contentnames, string[] contentsizes, string totaldirectory)
|
||||
{
|
||||
WriteStatus("Beginning WAD Pack...");
|
||||
// Directory stuff
|
||||
string currentdir = Application.StartupPath;
|
||||
if (!(currentdir.EndsWith(@"\")) || !(currentdir.EndsWith(@"/")))
|
||||
currentdir += @"\";
|
||||
|
||||
// Create cert file holder
|
||||
byte[] certsbuf = FileLocationToByteArray(currentdir + @"\cert.sys");
|
||||
//byte[] certsbuf = FileLocationToByteArray(currentdir + @"\cert.sys");
|
||||
byte[] certsbuf = new byte[0xA00];
|
||||
if (!(CertsValid()))
|
||||
{
|
||||
WriteStatus("Error: NUSD could not locate cached certs!");
|
||||
return;
|
||||
}
|
||||
for (int c = 0; c < cert_CA.Length; c++)
|
||||
{
|
||||
certsbuf[c] = cert_CA[c];
|
||||
}
|
||||
for (int c = 0; c < cert_CACP.Length; c++)
|
||||
{
|
||||
certsbuf[c + 0x400] = cert_CACP[c];
|
||||
}
|
||||
for (int c = 0; c < cert_CAXS.Length; c++)
|
||||
{
|
||||
certsbuf[c + 0x700] = cert_CAXS[c];
|
||||
}
|
||||
if (!(TotalCertValid(certsbuf)))
|
||||
{
|
||||
WriteStatus("Error: Cert array did not hash properly!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create ticket file holder
|
||||
byte[] cetkbuf = FileLocationToByteArray(totaldirectory + @"\cetk");
|
||||
@ -1132,7 +1173,7 @@ namespace NUS_Downloader
|
||||
// Write cert[] to 0x40.
|
||||
wadfs.Seek(0x40, SeekOrigin.Begin);
|
||||
wadfs.Write(certsbuf, 0, certsbuf.Length);
|
||||
WriteStatus("Cert wrote (0x" + Convert.ToString(64, 16) + ")");
|
||||
WriteStatus(" - Certs wrote (0x" + Convert.ToString(64, 16) + ")");
|
||||
|
||||
// Need 64 byte boundary...
|
||||
wadfs.Seek(2624, SeekOrigin.Begin);
|
||||
@ -1141,7 +1182,7 @@ namespace NUS_Downloader
|
||||
// Write ticket at this point...
|
||||
wad.TicketSize = 0x2A4;
|
||||
wadfs.Write(cetkbuf, 0, wad.TicketSize);
|
||||
WriteStatus("Ticket wrote (0x" + Convert.ToString((wadfs.Length - 0x2A4), 16) + ")");
|
||||
WriteStatus(" - Ticket wrote (0x" + Convert.ToString((wadfs.Length - 0x2A4), 16) + ")");
|
||||
|
||||
// Need 64 byte boundary...
|
||||
wadfs.Seek(ByteBoundary(Convert.ToInt32(wadfs.Length)), SeekOrigin.Begin);
|
||||
@ -1149,7 +1190,7 @@ namespace NUS_Downloader
|
||||
// Write TMD at this point...
|
||||
wad.TMDSize = 484 + (contentcount * 36);
|
||||
wadfs.Write(tmdbuf, 0, 484 + (contentcount * 36));
|
||||
WriteStatus("TMD wrote (0x" + Convert.ToString((wadfs.Length - (484 + (contentcount * 36))), 16) + ")");
|
||||
WriteStatus(" - TMD wrote (0x" + Convert.ToString((wadfs.Length - (484 + (contentcount * 36))), 16) + ")");
|
||||
|
||||
// Preliminary data size of wad file.
|
||||
wad.DataSize = 0;
|
||||
@ -1165,7 +1206,7 @@ namespace NUS_Downloader
|
||||
|
||||
wadfs.Write(contbuf, 0, contbuf.Length);
|
||||
|
||||
WriteStatus(contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ")");
|
||||
WriteStatus(" - " + contentnames[i] + " wrote (0x" + Convert.ToString((wadfs.Length - contbuf.Length), 16) + ")");
|
||||
HandleMismatch(int.Parse(contentsizes[i], System.Globalization.NumberStyles.HexNumber), contbuf.Length);
|
||||
|
||||
wad.DataSize += contbuf.Length;
|
||||
@ -1319,7 +1360,7 @@ namespace NUS_Downloader
|
||||
private void getcerts_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Get a certs.sys from NUS...
|
||||
|
||||
/*
|
||||
// Directory stuff
|
||||
string currentdir = Application.StartupPath;
|
||||
if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
|
||||
@ -1376,8 +1417,9 @@ namespace NUS_Downloader
|
||||
// Cleanup...
|
||||
File.Delete(currentdir + "cetk");
|
||||
File.Delete(currentdir + "tmd.289");
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
static string getMd5Hash(string input)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
@ -1412,7 +1454,7 @@ namespace NUS_Downloader
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
private void packbox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (packbox.Checked == true)
|
||||
@ -3332,5 +3374,83 @@ namespace NUS_Downloader
|
||||
WriteStatus(String.Format("{0}v{1}", TitleID, Version));
|
||||
}
|
||||
}
|
||||
|
||||
private void ScanForCerts(byte[] tmdortik)
|
||||
{
|
||||
|
||||
// For some reason a few 00s are cut off, so pad it up to be safe.
|
||||
tmdortik = PadToMultipleOf(tmdortik, 16);
|
||||
|
||||
// Search for cert_CACP
|
||||
if (!(tmdortik.Length < 0x300))
|
||||
for (int a = 0; a < (tmdortik.Length - 0x300); a++)
|
||||
{
|
||||
byte[] chunk = new byte[0x300];
|
||||
for (int b = 0; b < 0x300; b++)
|
||||
{
|
||||
chunk[b] = tmdortik[a + b];
|
||||
}
|
||||
if (Convert.ToBase64String(ComputeSHA(chunk)) == Convert.ToBase64String(cert_CACP_sha1))
|
||||
{
|
||||
cert_CACP = chunk;
|
||||
WriteStatus(" - Cert CA-CP Located!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for cert_CAXS
|
||||
if (!(tmdortik.Length < 0x300))
|
||||
for (int a = 0; a < (tmdortik.Length - 0x300); a++)
|
||||
{
|
||||
byte[] chunk = new byte[0x300];
|
||||
for (int b = 0; b < 0x300; b++)
|
||||
{
|
||||
chunk[b] = tmdortik[a + b];
|
||||
}
|
||||
if (Convert.ToBase64String(ComputeSHA(chunk)) == Convert.ToBase64String(cert_CAXS_sha1))
|
||||
{
|
||||
cert_CAXS = chunk;
|
||||
WriteStatus(" - Cert CA-XS Located!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for cert_CA
|
||||
if ((!(tmdortik.Length < 0x400)) && ((Convert.ToBase64String(cert_CA) != Convert.ToBase64String(cert_CA_sha1))))
|
||||
{
|
||||
for (int a = 0; a < (tmdortik.Length - 0x400); a++)
|
||||
{
|
||||
byte[] chunk = new byte[0x400];
|
||||
for (int b = 0; b < 0x400; b++)
|
||||
{
|
||||
chunk[b] = tmdortik[a + b];
|
||||
}
|
||||
if (Convert.ToBase64String(ComputeSHA(chunk)) == Convert.ToBase64String(cert_CA_sha1))
|
||||
{
|
||||
cert_CA = chunk;
|
||||
WriteStatus(" - Cert CA Located!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CertsValid()
|
||||
{
|
||||
if (Convert.ToBase64String(ComputeSHA(cert_CA)) != Convert.ToBase64String(cert_CA_sha1))
|
||||
return false;
|
||||
if (Convert.ToBase64String(ComputeSHA(cert_CACP)) != Convert.ToBase64String(cert_CACP_sha1))
|
||||
return false;
|
||||
if (Convert.ToBase64String(ComputeSHA(cert_CAXS)) != Convert.ToBase64String(cert_CAXS_sha1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TotalCertValid(byte[] cert_sys)
|
||||
{
|
||||
if (Convert.ToBase64String(ComputeSHA(cert_sys)) != Convert.ToBase64String(cert_total_sha1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<ManifestCertificateThumbprint>5828AACDBD1A48E3768B7E0465E90D0E96E2BE4C</ManifestCertificateThumbprint>
|
||||
<ManifestKeyFile>NUS Downloader_TemporaryKey.pfx</ManifestKeyFile>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
<SignManifests>true</SignManifests>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
|
@ -18,8 +18,8 @@
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
Loading…
Reference in New Issue
Block a user