package main import ( "crypto/rand" "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/base64" "encoding/pem" "fmt" "math/big" "net" "strings" "time" "software.sslmate.com/src/go-pkcs12" ) // Hardcoded certificate data - users need to replace these placeholders with actual certificate data const ( // Base64 encoded data of P12 certificate - users need to replace with actual cert.p12 file content hardcodedP12Data = `-----BEGIN CERTIFICATE----- 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 BBTOPefdAsbPZURS9djPzGhmw0NCbQICJxA= -----END CERTIFICATE-----` // PEM format data of CA certificate - users need to replace with actual CA.crt file content hardcodedCACert = `-----BEGIN CERTIFICATE----- MIIFOTCCBCGgAwIBAgIGAZi8TmIsMA0GCSqGSIb3DQEBCwUAMIGgMTEwLwYDVQQDDChDaGFybGVz IFByb3h5IENBICgxOCBBdWcgMjAyNSwgQkxBQ0stUEMpMSUwIwYDVQQLDBxodHRwczovL2NoYXJs ZXNwcm94eS5jb20vc3NsMREwDwYDVQQKDAhYSzcyIEx0ZDERMA8GA1UEBwwIQXVja2xhbmQxETAP BgNVBAgMCEF1Y2tsYW5kMQswCQYDVQQGEwJOWjAeFw0yNTA4MTcwODMxNTBaFw0yNjA4MTcwODMx NTBaMIGgMTEwLwYDVQQDDChDaGFybGVzIFByb3h5IENBICgxOCBBdWcgMjAyNSwgQkxBQ0stUEMp MSUwIwYDVQQLDBxodHRwczovL2NoYXJsZXNwcm94eS5jb20vc3NsMREwDwYDVQQKDAhYSzcyIEx0 ZDERMA8GA1UEBwwIQXVja2xhbmQxETAPBgNVBAgMCEF1Y2tsYW5kMQswCQYDVQQGEwJOWjCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKEmwh2Lk0017ak2c+3eKUGRsZVc5TSfcFaaiAk5 kKMWj0pIXNKo2G8eERo4BYNqZi+icHGWBwmhAuUDJqpZMji2Qzv0jvuFDw0+UVVtp30RU/92GZYV C44df+qPTYqUuD+ZPKdlo2RZ38Jbru/VT7AQQ53cvcBJ6s7WzY9QQVui1Rd3jHRXnyb9/duccw22 vo6f2/OX2mVEKpXd5/3g8d+D8EuoiTUKDbgM39diOYuelh8Xybf0Zy1ZU4nkYeaVwzf9djlgxa1E 2Qb9SscxddGBJxyTrqtoG4ZLwzuwz3DX6KOEPX73I0Q8L+TBf7KQhBYkHSOa6HygE0Vgi3HoM4UC AwEAAaOCAXUwggFxMA8GA1UdEwEB/wQFMAMBAf8wggEtBglghkgBhvhCAQ0EggEeE4IBGlRoaXMg cm9vdCBjZXJ0aWZpY2F0ZSB3YXMgZ2VuZXJhdGVkIGJ5IENoYXJsZXMgUHJveHkgZm9yIFNTTCBQ cm94eWluZy4gSWYgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBwYXJ0IG9mIGEgY2VydGlmaWNhdGUgY2hh aW4sIHRoaXMgbWVhbnMgdGhhdCB5b3UncmUgYnJvd3NpbmcgdGhyb3VnaCBDaGFybGVzIFByb3h5 IHdpdGggU1NMIFByb3h5aW5nIGVuYWJsZWQgZm9yIHRoaXMgd2Vic2l0ZS4gUGxlYXNlIHNlZSBo dHRwczovL2NoYXJsZXNwcm94eS5jb20vc3NsIGZvciBtb3JlIGluZm9ybWF0aW9uLjAOBgNVHQ8B Af8EBAMCAgQwHQYDVR0OBBYEFKBf+QLehq0dc4s7YMIUUFJdgWBfMA0GCSqGSIb3DQEBCwUAA4IB AQBc+K3gGnz00yv2XMYRMbeYLr3SD15Tx3NAPri08EY1wyyufkBCaI81tZSCMy4PkGAYN+zODrQ6 MRj0tbABTNZHdzFCuazE+B2ce2Ka3PcQ1DNpGf60NYk9qBHpOxak+5XxrECFYjStYW3gLZ7mZSnI YX9doSujRpzSbVZFvVh4J1zCzF1NuD6VxxfFjppJ6EnvnSSQOly0e32NzibQi3akFb4E5hn58py/ Eth3xl7mzWjcdKeKd30TAeg98PA+drJ8JsunIc2sICcNuAoVSKQEX4ihZHMhFLXl0MNdyWQtqHPR beQU9SvWF3DVmilrNO1neetL2TCZK5iMyIAHvqPo -----END CERTIFICATE-----` // P12 certificate password - users need to modify to actual password hardcodedP12Password = "Admin!23" ) // loadHardcodedCertificate loads hardcoded P12 certificate func loadHardcodedCertificate() (*tls.Config, error) { // If hardcoded data is empty or placeholder, generate self-signed certificate if len(hardcodedP12Data) < 100 { fmt.Println("Warning: No valid P12 certificate data provided, generating self-signed certificate for testing") return generateSelfSignedCert() } // Decode base64 data p12Data, err := decodeBase64String(hardcodedP12Data) if err != nil { fmt.Printf("Warning: Unable to decode P12 data (%v), generating self-signed certificate\n", err) return generateSelfSignedCert() } // Parse P12 data privateKey, cert, caCerts, err := pkcs12.DecodeChain(p12Data, hardcodedP12Password) if err != nil { fmt.Printf("Warning: Unable to parse P12 certificate (%v), generating self-signed certificate\n", err) return generateSelfSignedCert() } // Create certificate chain certificates := []tls.Certificate{ { Certificate: [][]byte{cert.Raw}, PrivateKey: privateKey, }, } // Create CA certificate pool caCertPool := x509.NewCertPool() for _, caCert := range caCerts { caCertPool.AddCert(caCert) } // If there's a hardcoded CA certificate, add it to the pool if len(hardcodedCACert) > 100 { block, _ := pem.Decode([]byte(hardcodedCACert)) if block != nil { if caCert, err := x509.ParseCertificate(block.Bytes); err == nil { caCertPool.AddCert(caCert) } } } return &tls.Config{ Certificates: certificates, RootCAs: caCertPool, InsecureSkipVerify: true, }, nil } // decodeBase64String decodes base64 string, ignoring whitespace and comments func decodeBase64String(data string) ([]byte, error) { // Remove comment lines and whitespace var cleanData strings.Builder lines := strings.SplitSeq(data, "\n") for line := range lines { line = strings.TrimSpace(line) if len(line) > 0 && !strings.HasPrefix(line, "--") { cleanData.WriteString(line) } } if cleanData.Len() == 0 { return nil, fmt.Errorf("no valid base64 data") } // Use standard base64 decoding return base64.StdEncoding.DecodeString(cleanData.String()) } // generateSelfSignedCert generates self-signed certificate for testing func generateSelfSignedCert() (*tls.Config, error) { // Generate private key privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } // Create certificate template template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ Organization: []string{"MITM Proxy"}, OrganizationalUnit: []string{"MITM Proxy CA"}, Country: []string{"US"}, Province: []string{""}, Locality: []string{""}, StreetAddress: []string{""}, PostalCode: []string{""}, CommonName: "MITM Proxy Root CA", }, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), // Proper key usage for CA certificate KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign, // Extended key usage for server authentication ExtKeyUsage: []x509.ExtKeyUsage{ x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth, }, BasicConstraintsValid: true, IsCA: true, MaxPathLen: 0, MaxPathLenZero: true, // Add Subject Alternative Names for flexibility DNSNames: []string{ "localhost", "*.localhost", "127.0.0.1", }, IPAddresses: []net.IP{ net.IPv4(127, 0, 0, 1), net.IPv6loopback, }, } // Generate certificate certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) if err != nil { return nil, err } // Create TLS certificate cert := tls.Certificate{ Certificate: [][]byte{certDER}, PrivateKey: privateKey, } return &tls.Config{ Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true, }, nil } // getHardcodedCACert returns hardcoded CA certificate func getHardcodedCACert() string { return hardcodedCACert }