/sys/cert.sys

From WiiBrew
Jump to navigation Jump to search
/sys/cert.sys
TypeGeneric file
OwnerIOS
Group ID0

/sys/cert.sys is a certificate store. It contains certificates that have been encountered by ES (except ECC certificates). This file can be easily dumped using Simple cert.sys Extractor.

Creation

IOS creates this file if it tries to import a title and this file does not exist, however, under normal circumstances, this does not happen; boot2v0 instead creates it when it loads the 1-2 title from the SD card. Given the order of the certificates in this file, it appears that this 1-2 title has a ticket and TMD.

Entries

On an up-to-date Wii, the store has 3 certificates (in this order):

  • XS00000003 (issued by Root-CA00000001), used to sign tickets
  • CA00000001 (issued by Root)
  • CP00000004 (issued by Root-CA00000001), used to sign TMDs

The root certificate is embedded inside of the IOS kernel, inside of IOSC code.

Uses

The store is used by ES when verifying a signed container. This typically only happens during an import. The verification function may or may not update /sys/cert.sys with any new encountered certificates depending on parameters passed to it.

The intermediate certificate is always the first certificate being inserted, followed by its issuer (which is the CA).

Function Store can be updated
ImportTicket Yes
ImportTitleInit (TMD) Yes
ImportTitleInit (Ticket) No
ImportTmd Yes
SetupStreamKey (TMD) Yes
SetupStreamKey (Ticket) Yes
ListTmdContents / GetTMDStoredContents Yes

Structure

The structure of each certificate entry is documented below:

enum SignatureType : u32
{
  RSA4096 = 0x00010000,
  RSA2048 = 0x00010001,
  ECC = 0x00010002,
};

enum PublicKeyType : u32
{
  RSA4096 = 0,
  RSA2048 = 1,
};

struct SignatureRSA4096
{
  SignatureType type;
  u8 sig[0x200];
  u8 fill[0x3c];
  char issuer[0x40];
}; // sizeof() = 0x280

struct SignatureRSA2048
{
  SignatureType type;
  u8 sig[0x100];
  u8 fill[0x3c];
  char issuer[0x40];
}; // sizeof() = 0x180

struct SignatureECC
{
  SignatureType type;
  u8 sig[0x3c];
  u8 fill[0x40];
  char issuer[0x40];
}; // sizeof() = 0xc0

struct CertHeader
{
  PublicKeyType public_key_type;
  char name[0x40];
  u32 id;
};

struct CertRSA4096
{
  SignatureRSA4096 signature;
  CertHeader header;
  // The signature is RSA4096, but the key is a RSA2048 public key,
  // so its size is 0x100, not 0x200, as one would expect from the name.
  u8 public_key[0x100];
  u8 exponent[0x4];
  u8 pad[0x34];
}; // sizeof() = 0x400

struct CertRSA2048
{
  SignatureRSA2048 signature;
  CertHeader header;
  u8 public_key[0x100];
  u8 exponent[0x4];
  u8 pad[0x34];
}; // sizeof() = 0x300

struct CertECC
{
  SignatureECC signature;
  CertHeader header;
  u8 data[0x3c];
  u8 pad[0x3c];
}; // sizeof() = 0x300

union Cert
{
  CertRSA4096 rsa4096;
  CertRSA2048 rsa2048;
  CertECC ecc;
};