WiiMart-Patcher/cert_store.go
2021-12-30 02:56:07 -06:00

102 lines
3.0 KiB
Go

package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"time"
)
// generateSerial generates a random serial number for our issued certificates.
// It is taken from golang std: src/crypto/tls/generate_cert.go
// Direct permalink on GitHub: https://git.io/JyyDw
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)
}
return serialNumber
}
func createCertificates() []byte {
////////////////////////////////////
// Generate root CA //
////////////////////////////////////
rootCA := x509.Certificate{
SignatureAlgorithm: x509.SHA1WithRSA,
SerialNumber: generateSerial(),
Subject: pkix.Name{
CommonName: "Open Shop Channel CA",
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
KeyUsage: x509.KeyUsageCertSign,
BasicConstraintsValid: true,
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)
check(err)
rootCertBytes, err := x509.CreateCertificate(rand.Reader, &rootCA, &rootCA, &rootPriv.PublicKey, rootPriv)
check(err)
////////////////////////////////////
// Issue server TLS certificate //
////////////////////////////////////
serverCert := x509.Certificate{
SignatureAlgorithm: x509.SHA1WithRSA,
SerialNumber: generateSerial(),
// We'll issue with a primary common name for our base domain.
Subject: pkix.Name{
CommonName: baseDomain,
},
// The SAN will be a wildcard for our base domain, as it cannot be the CN.
DNSNames: []string{
"*." + baseDomain,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
// TODO: what's non-repudiation
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
IsCA: false,
MaxPathLenZero: true,
}
serverPriv, err := rsa.GenerateKey(rand.Reader, 2048)
check(err)
serverCertBytes, err := x509.CreateCertificate(rand.Reader, &serverCert, &rootCA, &rootPriv.PublicKey, serverPriv)
check(err)
////////////////////////////
// Persist certificates //
////////////////////////////
rootCertPem := pemEncode("CERTIFICATE", rootCertBytes)
rootKeyPem := pemEncode("RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(rootPriv))
serverCertPem := pemEncode("CERTIFICATE", serverCertBytes)
serverKeyPem := pemEncode("RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(serverPriv))
writeOut("root.pem", rootCertPem)
writeOut("root.cer", rootCertBytes)
writeOut("root.key", rootKeyPem)
writeOut("server.pem", serverCertPem)
writeOut("server.key", serverKeyPem)
return rootCertBytes
}
func pemEncode(typeName string, bytes []byte) []byte {
block := pem.Block{Type: typeName, Bytes: bytes}
return pem.EncodeToMemory(&block)
}