mirror of
https://github.com/NinjaCheetah/libWiiPy.git
synced 2025-04-25 12:51:01 -04:00
Handle cert chain data in a title as a CertificateChain instead of bytes
This commit is contained in:
parent
ece19177c4
commit
8a15b1e82e
@ -40,10 +40,10 @@ def download_title(title_id: str, title_version: int = None, wiiu_endpoint: bool
|
||||
"""
|
||||
# First, create the new title.
|
||||
title = Title()
|
||||
# Download and load the TMD, Ticket, and certs.
|
||||
# Download and load the certificate chain, TMD, and Ticket.
|
||||
title.load_cert_chain(download_cert_chain(wiiu_endpoint, endpoint_override))
|
||||
title.load_tmd(download_tmd(title_id, title_version, wiiu_endpoint, endpoint_override))
|
||||
title.load_ticket(download_ticket(title_id, wiiu_endpoint, endpoint_override))
|
||||
title.wad.set_cert_data(download_cert(wiiu_endpoint, endpoint_override))
|
||||
# Download all contents
|
||||
title.load_content_records()
|
||||
title.content.content_list = download_contents(title_id, title.tmd, wiiu_endpoint, endpoint_override)
|
||||
@ -146,9 +146,9 @@ def download_ticket(title_id: str, wiiu_endpoint: bool = False, endpoint_overrid
|
||||
return ticket
|
||||
|
||||
|
||||
def download_cert(wiiu_endpoint: bool = False, endpoint_override: str = None) -> bytes:
|
||||
def download_cert_chain(wiiu_endpoint: bool = False, endpoint_override: str = None) -> bytes:
|
||||
"""
|
||||
Downloads the signing certificate used by all WADs. This uses System Menu 4.3U as the source.
|
||||
Downloads the signing certificate chain used by all WADs. This uses System Menu 4.3U as the source.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@ -163,7 +163,7 @@ def download_cert(wiiu_endpoint: bool = False, endpoint_override: str = None) ->
|
||||
bytes
|
||||
The cert file.
|
||||
"""
|
||||
# Download the TMD and cetk for the System Menu 4.3U.
|
||||
# Download the TMD and cetk for System Menu 4.3U (v513).
|
||||
if endpoint_override is not None:
|
||||
endpoint_url = _validate_endpoint(endpoint_override)
|
||||
else:
|
||||
@ -175,18 +175,18 @@ def download_cert(wiiu_endpoint: bool = False, endpoint_override: str = None) ->
|
||||
cetk_url = endpoint_url + "0000000100000002/cetk"
|
||||
tmd = requests.get(url=tmd_url, headers={'User-Agent': 'wii libnup/1.0'}, stream=True).content
|
||||
cetk = requests.get(url=cetk_url, headers={'User-Agent': 'wii libnup/1.0'}, stream=True).content
|
||||
# Assemble the certificate.
|
||||
cert = b''
|
||||
# Assemble the certificate chain.
|
||||
cert_chain = b''
|
||||
# Certificate Authority data.
|
||||
cert += cetk[0x2A4 + 768:]
|
||||
# Certificate Policy data.
|
||||
cert += tmd[0x328:0x328 + 768]
|
||||
# XS data.
|
||||
cert += cetk[0x2A4:0x2A4 + 768]
|
||||
# Since the cert is always the same, check the hash to make sure nothing went wildly wrong.
|
||||
if hashlib.sha1(cert).hexdigest() != "ace0f15d2a851c383fe4657afc3840d6ffe30ad0":
|
||||
cert_chain += cetk[0x2A4 + 768:]
|
||||
# Certificate Policy (TMD certificate) data.
|
||||
cert_chain += tmd[0x328:0x328 + 768]
|
||||
# XS (Ticket certificate) data.
|
||||
cert_chain += cetk[0x2A4:0x2A4 + 768]
|
||||
# Since the cert chain is always the same, check the hash to make sure nothing went wildly wrong.
|
||||
if hashlib.sha1(cert_chain).hexdigest() != "ace0f15d2a851c383fe4657afc3840d6ffe30ad0":
|
||||
raise Exception("An unknown error has occurred downloading and creating the certificate.")
|
||||
return cert
|
||||
return cert_chain
|
||||
|
||||
|
||||
def download_content(title_id: str, content_id: int, wiiu_endpoint: bool = False,
|
||||
|
@ -4,6 +4,7 @@
|
||||
# See https://wiibrew.org/wiki/Title for details about how titles are formatted
|
||||
|
||||
import math
|
||||
from .cert import CertificateChain
|
||||
from .content import ContentRegion
|
||||
from .ticket import Ticket
|
||||
from .tmd import TMD
|
||||
@ -19,17 +20,20 @@ class Title:
|
||||
|
||||
Attributes
|
||||
----------
|
||||
wad : WAD
|
||||
wad: WAD
|
||||
A WAD object of a WAD containing the title's data.
|
||||
tmd : TMD
|
||||
cert_chain: CertificateChain
|
||||
The chain of certificates used to verify the contents of a title.
|
||||
tmd: TMD
|
||||
A TMD object of the title's TMD.
|
||||
ticket : Ticket
|
||||
ticket: Ticket
|
||||
A Ticket object of the title's Ticket.
|
||||
content: ContentRegion
|
||||
A ContentRegion object containing the title's contents.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.wad: WAD = WAD()
|
||||
self.cert_chain: CertificateChain = CertificateChain()
|
||||
self.tmd: TMD = TMD()
|
||||
self.ticket: Ticket = Ticket()
|
||||
self.content: ContentRegion = ContentRegion()
|
||||
@ -47,6 +51,9 @@ class Title:
|
||||
# Create a new WAD object based on the WAD data provided.
|
||||
self.wad = WAD()
|
||||
self.wad.load(wad)
|
||||
# Load the certificate chain.
|
||||
self.cert_chain = CertificateChain()
|
||||
self.cert_chain.load(self.wad.get_cert_data())
|
||||
# Load the TMD.
|
||||
self.tmd = TMD()
|
||||
self.tmd.load(self.wad.get_tmd_data())
|
||||
@ -75,6 +82,8 @@ class Title:
|
||||
# Set WAD type to ib if the title being packed is boot2.
|
||||
if self.tmd.title_id == "0000000100000001":
|
||||
self.wad.wad_type = "ib"
|
||||
# Dump the certificate chain and set it in the WAD.
|
||||
self.wad.set_cert_data(self.cert_chain.dump())
|
||||
# Dump the TMD and set it in the WAD.
|
||||
# This requires updating the content records and number of contents in the TMD first.
|
||||
self.tmd.content_records = self.content.content_records # This may not be needed because it's a ref already
|
||||
@ -87,6 +96,19 @@ class Title:
|
||||
self.wad.set_content_data(content_data, content_size)
|
||||
return self.wad.dump()
|
||||
|
||||
def load_cert_chain(self, cert_chain: bytes) -> None:
|
||||
"""
|
||||
Load an existing certificate chain into the title. Note that this will overwrite any existing certificate chain
|
||||
data for this title.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cert_chain: bytes
|
||||
The data for the certificate chain to load.
|
||||
"""
|
||||
self.cert_chain.load(cert_chain)
|
||||
|
||||
|
||||
def load_tmd(self, tmd: bytes) -> None:
|
||||
"""
|
||||
Load existing TMD data into the title. Note that this will overwrite any existing TMD data for this title.
|
||||
@ -94,9 +116,8 @@ class Title:
|
||||
Parameters
|
||||
----------
|
||||
tmd : bytes
|
||||
The data for the WAD you wish to load.
|
||||
The data for the TMD to load.
|
||||
"""
|
||||
# Load TMD.
|
||||
self.tmd.load(tmd)
|
||||
|
||||
def load_ticket(self, ticket: bytes) -> None:
|
||||
@ -107,9 +128,8 @@ class Title:
|
||||
Parameters
|
||||
----------
|
||||
ticket : bytes
|
||||
The data for the WAD you wish to load.
|
||||
The data for the Ticket to load.
|
||||
"""
|
||||
# Load Ticket.
|
||||
self.ticket.load(ticket)
|
||||
|
||||
def load_content_records(self) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user