From 952c3824e3cf39ebfac2f5a860661e17c53aae42 Mon Sep 17 00:00:00 2001 From: Spotlight Date: Wed, 16 Mar 2022 17:33:36 -0500 Subject: [PATCH] Resolve certificate generation The server certificate was mistakenly using the public key of the CA and private key of itself, instead of the reverse. We additionally bump the CA size to 2048 bytes. --- README.md | 4 ++-- cert_store.go | 32 +++++++++++++------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 78b2c35..b69aad5 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ Invoke WSC-Patcher similar to the following: ``` Throughout its operation, the patcher will perform the following: - - Version 20 (latest, as of writing) of the Wii Shop Channel will be downloaded to `cache/original.wad`. - - If `output/root.cer` is not present, a 1024-bit (RSA), SHA-1 CA certificate will be generated. + - Version 21 (latest, as of writing) of the Wii Shop Channel will be downloaded to `cache/original.wad`. + - If `output/root.cer` is not present, a 2048-bit (RSA), SHA-1 CA certificate will be generated. - At the same time, `*.` will be issued for ease of use. See `output/server.pem` and `output/server.key` for usage with nginx or similar servers. - Modifications are made to the application's main `.arc` (within content index 2) to permit Opera loading the base domain, and the customized certificates. - Patches to the application's main dol are also performed. Please see `docs/patch_.md` for more information on what these contain. diff --git a/cert_store.go b/cert_store.go index e88501b..3fa9a70 100644 --- a/cert_store.go +++ b/cert_store.go @@ -6,7 +6,6 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" - "log" "math/big" "time" ) @@ -17,9 +16,7 @@ import ( func generateSerial() *big.Int { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - log.Fatalf("Failed to generate serial number: %v", err) - } + check(err) return serialNumber } @@ -28,7 +25,7 @@ func createCertificates() []byte { //////////////////////////////////// // Generate root CA // //////////////////////////////////// - rootCA := x509.Certificate{ + rootCAFormat := x509.Certificate{ SignatureAlgorithm: x509.SHA1WithRSA, SerialNumber: generateSerial(), Subject: pkix.Name{ @@ -41,18 +38,16 @@ func createCertificates() []byte { IsCA: true, } - // Sadly, 2048 bits can cause compatability issues with IOS. We must use 1024. - // TODO(spotlightishere): Is it possible to raise to 2048 anyway? - rootPriv, err := rsa.GenerateKey(rand.Reader, 1024) + rootPriv, err := rsa.GenerateKey(rand.Reader, 2048) check(err) - rootCertBytes, err := x509.CreateCertificate(rand.Reader, &rootCA, &rootCA, &rootPriv.PublicKey, rootPriv) + rootCert, err := x509.CreateCertificate(rand.Reader, &rootCAFormat, &rootCAFormat, &rootPriv.PublicKey, rootPriv) check(err) //////////////////////////////////// // Issue server TLS certificate // //////////////////////////////////// - serverCert := x509.Certificate{ + serverCertFormat := x509.Certificate{ SignatureAlgorithm: x509.SHA1WithRSA, SerialNumber: generateSerial(), // We'll issue with a primary common name for our base domain. @@ -63,10 +58,9 @@ func createCertificates() []byte { DNSNames: []string{ "*." + baseDomain, }, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(10, 0, 0), - // TODO: what's non-repudiation - KeyUsage: x509.KeyUsageDigitalSignature, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(10, 0, 0), + KeyUsage: x509.KeyUsageKeyAgreement | x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, IsCA: false, MaxPathLenZero: true, @@ -75,24 +69,24 @@ func createCertificates() []byte { serverPriv, err := rsa.GenerateKey(rand.Reader, 2048) check(err) - serverCertBytes, err := x509.CreateCertificate(rand.Reader, &serverCert, &rootCA, &rootPriv.PublicKey, serverPriv) + serverCert, err := x509.CreateCertificate(rand.Reader, &serverCertFormat, &rootCAFormat, &serverPriv.PublicKey, rootPriv) check(err) //////////////////////////// // Persist certificates // //////////////////////////// - rootCertPem := pemEncode("CERTIFICATE", rootCertBytes) + rootCertPem := pemEncode("CERTIFICATE", rootCert) rootKeyPem := pemEncode("RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(rootPriv)) - serverCertPem := pemEncode("CERTIFICATE", serverCertBytes) + serverCertPem := pemEncode("CERTIFICATE", serverCert) serverKeyPem := pemEncode("RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(serverPriv)) writeOut("root.pem", rootCertPem) - writeOut("root.cer", rootCertBytes) + writeOut("root.cer", rootCert) writeOut("root.key", rootKeyPem) writeOut("server.pem", serverCertPem) writeOut("server.key", serverKeyPem) - return rootCertBytes + return rootCert } func pemEncode(typeName string, bytes []byte) []byte {