Added ability to re-encrypt vWii WAD Title Keys with the common key

This allows the creation of WADs that can be installed from *within* vWii mode, instead of just from Wii U mode.
This commit is contained in:
Campbell 2024-05-03 22:39:37 -04:00
parent 95dd93b85f
commit ec16050d6f
4 changed files with 42 additions and 19 deletions

View File

@ -1,6 +1,5 @@
# NUSGet.py, licensed under the MIT license
# Copyright 2024 NinjaCheetah
import sys
import os
import json
@ -125,8 +124,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.log_text += new_text + "\n"
self.ui.log_text_browser.setText(self.log_text)
# Always auto-scroll to the bottom of the log.
scrollBar = self.ui.log_text_browser.verticalScrollBar()
scrollBar.setValue(scrollBar.maximum())
scroll_bar = self.ui.log_text_browser.verticalScrollBar()
scroll_bar.setValue(scroll_bar.maximum())
def load_title_data(self, selected_title, selected_version, selected_region=None):
# Use the information passed from the double click callback to prepare a title for downloading.
@ -168,15 +167,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Throw an error and make a message box appear if you haven't selected any options to output the title.
if (self.ui.pack_wad_chkbox.isChecked() is False and self.ui.keep_enc_chkbox.isChecked() is False and
self.ui.create_dec_chkbox.isChecked() is False):
msgBox = QMessageBox()
msgBox.setIcon(QMessageBox.Icon.Critical)
msgBox.setStandardButtons(QMessageBox.StandardButton.Ok)
msgBox.setDefaultButton(QMessageBox.StandardButton.Ok)
msgBox.setWindowTitle("No Output Selected")
msgBox.setText("You have not selected any format to output the data in!")
msgBox.setInformativeText("Please select at least one option for how you would like the download to be "
"saved.")
msgBox.exec()
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Icon.Critical)
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
msg_box.setWindowTitle("No Output Selected")
msg_box.setText("You have not selected any format to output the data in!")
msg_box.setInformativeText("Please select at least one option for how you would like the download to be "
"saved.")
msg_box.exec()
return
# Lock the UI prior to the download beginning to avoid spawning multiple threads or changing info part way in.
self.ui.tid_entry.setEnabled(False)
@ -187,6 +186,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.ui.create_dec_chkbox.setEnabled(False)
self.ui.use_local_chkbox.setEnabled(False)
self.ui.use_wiiu_nus_chkbox.setEnabled(False)
self.ui.pack_vwii_mode_chkbox.setEnabled(False)
self.ui.wad_file_entry.setEnabled(False)
self.log_text = ""
self.ui.log_text_browser.setText(self.log_text)
@ -241,6 +241,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.ui.create_dec_chkbox.setEnabled(True)
self.ui.use_local_chkbox.setEnabled(True)
self.ui.use_wiiu_nus_chkbox.setEnabled(True)
self.ui.pack_vwii_mode_chkbox.setEnabled(True)
if self.ui.pack_wad_chkbox.isChecked() is True:
self.ui.wad_file_entry.setEnabled(True)
@ -358,6 +359,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
return -3
# If pack WAD is still true, pack the TMD, ticket, and contents all into a WAD.
if pack_wad_enabled is True:
# If the option to pack for vWii mode instead of Wii U mode is enabled, then the Title Key needs to be
# re-encrypted with the common key instead of the vWii key, so that the title can be installed from within
# vWii mode. (vWii mode does not have access to the vWii key, only Wii U mode has that.)
if self.ui.pack_vwii_mode_chkbox.isChecked() is True and (tid[3] == "7" or tid[7] == "7"):
progress_callback.emit(" - Re-encrypting Title Key with the common key...")
title_key_dec = title.ticket.get_title_key()
title_key_common = libWiiPy.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
title.ticket.common_key_index = 0
title.ticket.title_key_enc = title_key_common
# Get the WAD certificate chain, courtesy of libWiiPy.
progress_callback.emit(" - Building certificate...")
title.wad.set_cert_data(libWiiPy.download_cert(wiiu_endpoint=wiiu_nus_enabled))

View File

@ -78,6 +78,11 @@ class Ui_MainWindow(object):
self.verticalLayout_4.addWidget(self.vwii_title_tree)
self.pack_vwii_mode_chkbox = QCheckBox(self.vwii_tab)
self.pack_vwii_mode_chkbox.setObjectName(u"pack_vwii_mode_chkbox")
self.verticalLayout_4.addWidget(self.pack_vwii_mode_chkbox)
self.platform_tabs.addTab(self.vwii_tab, "")
self.verticalLayout.addWidget(self.platform_tabs)
@ -163,7 +168,7 @@ class Ui_MainWindow(object):
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 610, 30))
self.menubar.setGeometry(QRect(0, 0, 610, 29))
MainWindow.setMenuBar(self.menubar)
self.retranslateUi(MainWindow)
@ -178,6 +183,7 @@ class Ui_MainWindow(object):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.label_2.setText(QCoreApplication.translate("MainWindow", u"Available Titles", None))
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.wii_tab), QCoreApplication.translate("MainWindow", u"Wii", None))
self.pack_vwii_mode_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack for vWii mode instead of Wii U mode", None))
self.platform_tabs.setTabText(self.platform_tabs.indexOf(self.vwii_tab), QCoreApplication.translate("MainWindow", u"vWii", None))
self.tid_entry.setText("")
self.tid_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"Title ID", None))
@ -188,8 +194,8 @@ class Ui_MainWindow(object):
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;\"><br /></p></body></html>", None))
"</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", None))
self.pack_wad_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack WAD", None))
self.wad_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep encrypted contents", None))

View File

@ -107,6 +107,13 @@
</column>
</widget>
</item>
<item>
<widget class="QCheckBox" name="pack_vwii_mode_chkbox">
<property name="text">
<string>Pack for vWii mode instead of Wii U mode</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -165,8 +172,8 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -238,7 +245,7 @@ p, li { white-space: pre-wrap; }
<x>0</x>
<y>0</y>
<width>610</width>
<height>30</height>
<height>29</height>
</rect>
</property>
</widget>

View File

@ -1,4 +1,4 @@
pyside6
nuitka
git+https://github.com/NinjaCheetah/libWiipy
git+https://github.com/NinjaCheetah/libWiiPy
zstandard