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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 -----END CERTIFICATE----- ` // PEM format data of CA certificate - users need to replace with actual CA.crt file content hardcodedCACert = `-----BEGIN CERTIFICATE----- MIIDOTCCAiECFD7rRtWb2t27PCZVuQJmuY6owrI0MA0GCSqGSIb3DQEBCwUAMFkx CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJTSDELMAkGA1UEBwwCU0gxITAfBgNVBAoM GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwETUlUTTAeFw0yNTEx MDIxMTQ0NTVaFw0zNTEwMzExMTQ0NTVaMFkxCzAJBgNVBAYTAkNOMQswCQYDVQQI DAJTSDELMAkGA1UEBwwCU0gxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 IEx0ZDENMAsGA1UEAwwETUlUTTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBALoEwz9kS6HVq2TLWYUx/nZtR9riUe1jximA/zqSTEyUNlx0teS5pjNQIMV4 fYfDCY0XCSaeqM0psNcSXPW+i3kRaOaMb8eGDC6fFPEIrW8j3YP7q7pxZP9OxVHK 6ExCXp4cQaV9aWgDBp5VQOI4DRRWnDOejN5OCgM7BtsRaULYqu6RZXI0+m/RRFn0 7CRk9JfOb9Sp7qScQd3XiGV+sFN9HHW+IMEgYxlbv+Xh1JBJLPvrsYNmb8HIHOeB pT1jneVyjjwrCdAzv2g/jJj5X9m8y7mq+z/9aR5tiRddzcLFX7M3lkaZXz4No/EW MmqyWDZ3Z1+0kICv9KVu9g5B0n8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAETdb oFes544yy3DGvpGbRbDTcCTSBceNglyAYOLuRvUAJMoica+xeN9oTrymDX7prirM B0yIJIdBGNMsmlCV0rxzXAc3TsqFaNsQULFynpLLwCjS21wt0dY5ifn9R2cbk3Kr i2Pye++CuzQXgLNpyMs52USUoZC/4Yn6kEwtJ80rnTSnnpdwIm2+IKauNj2cqjk/ M7Zmpe8q3/393VTypxGT/pT/sTqyYlfQBxMDjUceWCC4suFY/PxL9wgahhXknjAd WgKzQq/PcMdqvNpQLQd2nRLbiJCzz2IC/ivYB0+OakcDbRQ7kcxrO2eWJK+Wliz1 XzFo0MZnM+Qp7Srm6Q== -----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 }