diff --git a/main.go b/main.go index a83f301..53711ef 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "context" "crypto/tls" "encoding/pem" @@ -22,9 +23,8 @@ import ( "strings" "time" - "golang.org/x/net/http2" - "github.com/fatih/color" + "golang.org/x/net/http2" ) const ( @@ -142,19 +142,19 @@ func main() { // readClientCert - helper function to read client certificate // from pem formatted file -func readClientCert(filename string) []tls.Certificate { +func readClientCert(filename string) ([]tls.Certificate, error) { if filename == "" { - return nil + return nil, nil } var ( pkeyPem []byte - certPem []byte + certPem bytes.Buffer ) // read client certificate file (must include client private key and certificate) - certFileBytes, err := ioutil.ReadFile(clientCertFile) + certFileBytes, err := ioutil.ReadFile(filename) if err != nil { - log.Fatalf("failed to read client certificate file: %v", err) + return nil, fmt.Errorf("failed to read client certificate file: %v", err) } for { @@ -168,15 +168,19 @@ func readClientCert(filename string) []tls.Certificate { pkeyPem = pem.EncodeToMemory(block) } if strings.HasSuffix(block.Type, "CERTIFICATE") { - certPem = pem.EncodeToMemory(block) + err = pem.Encode(&certPem, block) + if err != nil { + return nil, fmt.Errorf("failed to read client certificate file: %v", err) + } } } - cert, err := tls.X509KeyPair(certPem, pkeyPem) + cert, err := tls.X509KeyPair(certPem.Bytes(), pkeyPem) if err != nil { - log.Fatalf("unable to load client cert and key pair: %v", err) + return nil, fmt.Errorf("unable to load client cert and key pair: %v", err) } - return []tls.Certificate{cert} + + return []tls.Certificate{cert}, nil } func parseURL(uri string) *url.URL { @@ -269,10 +273,15 @@ func visit(url *url.URL) { host = req.Host } + cert, err := readClientCert(clientCertFile) + if err != nil { + log.Fatal(err) + } + tr.TLSClientConfig = &tls.Config{ ServerName: host, InsecureSkipVerify: insecure, - Certificates: readClientCert(clientCertFile), + Certificates: cert, } // Because we create a custom TLSClientConfig, we have to opt-in to HTTP/2. diff --git a/main_test.go b/main_test.go index 849e3d0..2f34769 100644 --- a/main_test.go +++ b/main_test.go @@ -22,3 +22,17 @@ func TestParseURL(t *testing.T) { } } } + +func TestReadClientCert(t *testing.T) { + _, err := readClientCert("./test/singlecert.pem") + + if err != nil { + t.Errorf("unable to read single cert and key: %v", err) + } + + _, err = readClientCert("./test/multicert.pem") + + if err != nil { + t.Errorf("unable to read multiple certs and key: %v", err) + } +} diff --git a/test/multicert.pem b/test/multicert.pem new file mode 100644 index 0000000..a885fc9 --- /dev/null +++ b/test/multicert.pem @@ -0,0 +1,124 @@ +-----BEGIN CERTIFICATE----- +MIIFBDCCAuygAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYUxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtFeGFtcGxlIE9yZzEqMCgG +A1UECwwhRXhhbXBsZSBPcmcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQD +DBZFeGFtcGxlIE9yZyBJc3N1aW5nIENBMB4XDTE4MTAyNDEzMzUyOVoXDTE5MTEw +MzEzMzUyOVowPDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0V4YW1wbGUgT3JnMRcw +FQYDVQQDDA5jbGllbnQuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANAEfdfAr+rQohrxIcP0V7WSWnWmyxtmBArUyd2qT4tDFNfSypxxS8Q/ +0nJNpfaLNwmeKXQFGZN2VtryquL0bJifORbVy3vXj9H7j+TT9YxQqk/ABQAfT8jm +MA30o1LAR0ywq9VxPIbaCqnS6FqnhporRBu6BVcQhJKGvBWBUFMCSM08Qgh1Hs7T +xerMGJG1/mW3Q8MMyJVsK2ElvaMXIoq8ZKDJoEPgDUzDh3WihegGoMRqacECyYxH +cJ4UG59GFncR4QvRv52YPl8JC8ijcp87qNePWqrs4zc3fNLbFg2EGQpotIohYNy1 +43ErDW/LX5rSkRFGhdxBp1Smje0ucaECAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEG +CWCGSAGG+EIBAQQEAwIFoDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0 +ZWQgQ2xpZW50IENlcnRpZmljYXRlMB0GA1UdDgQWBBQC8nA+9cHnnSlSNEJkAOmB +r9rlfDAfBgNVHSMEGDAWgBR0fSK3+61WDbt5berdyOeE1U3ckTAOBgNVHQ8BAf8E +BAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEB +CwUAA4ICAQAKG0Orwjf6q/AdCV+HcYLRDCZuXDHmK6AAYpwo0QUROt5WCTXp71LS +MfTo3HrWnAukhEkyTwpoNQZ7cnWtxnfT1o7Dhl+DTOluc67imRQk4QD8p+vvIsTS +87OHF/94/0rGVWuiBTWX3sDiuV9MKTWn13Fyc1L/btRKM48ax3/P/IeAv8Hrn9PG +mxS/soRkP/VQqAm4E+BjRSkydcd5lnPoSARjVPBuhxL7MpkGIZcJ2IitRtHmSMij +py8LAGa8fHN8OauqimuCvNhlEmq9rDt0YzgbyHTwQdb7p1Kr4lhEs34WBbW0SqEY +KwWkGnJEMbe5CXt04SlkEZs1tKL7M4w05sKqiiDXEg2mxW9U/hEJqW9LK8HUwtd1 +W7o0JPdNC36CUaThRmrQouuaVWd3lltWA2MxTRTriFFci7AefWcKet9xDnVXrvao +mzL0/VGJJLeCV4UEEcAm3h+g0s9cSWfm+bGRoaqcPHKoLJUm6hpJN8PCQeupr0Ix +uCqNojNIjfAPz8NU5bIPOCJxi2BAZaRuIGfOpi2pG0hNDJ3yMkDExHMIGHSxQSTE +l0wHN74JRWVpf7ZD8damp0wvZoFCrXKq6KuR3Vvh1qbKDZZ2DEKi/aNDm6XKvIZc +rHza19g1Ha52SbMuast7BghPxL0JEItyYqVex5jIjY7/UYqFOGhJBQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtFeGFtcGxlIE9yZzEqMCgG +A1UECwwhRXhhbXBsZSBPcmcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRwwGgYDVQQD +DBNFeGFtcGxlIE9yZyBSb290IENBMB4XDTE4MTAyNDEzMzAxOVoXDTI4MTAyMTEz +MzAxOVowgYUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYD +VQQKDAtFeGFtcGxlIE9yZzEqMCgGA1UECwwhRXhhbXBsZSBPcmcgQ2VydGlmaWNh +dGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZFeGFtcGxlIE9yZyBJc3N1aW5nIENBMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArhfpnsaVYU79YXYaoaizB3N/ +JmJXBZqzXIboY+KBVq+TfXzafBR4rjWYxwImSwUHBqVOV9VS56vIk1hSiDd2sruz +uRkyedXx3U7KLl6Ec0livEQpMaQj86JVxf2brQiSqmmbkN+qhvNuSQdTgpNKv02n +hyOuDSz/0+rEOmDy9NDXvK+kvcJQJS/Qx2kKyjV/QjVRxnWH9K3Byl0kqZ4wYz3S +qXA7t54r2ZH4VC2+zj7lfTWJhfPzP4pw670lXzUoSgcVFVBCwySb1rZ8eLrC8Omn +Mjz8vjb3pf2Z3HVfQtIbVCgorvIBj88DMnADGX7UX9nuP0UJx/UYQr0ssDLMiQXh +9BAir8IlSci0PjAaqderreaz+coASvE8J3f1dWft8lid4KbZneCLe4NotFHc1c3e +QBz9A9OpqjbtRQBJC9Y0yi/MyIzHdGlh2Yx/N9zggCX0wirRjOfMir/W5ygBkgPw +K9do8m3IYvxNHPeX0lCP8OAcDfw8Nxgsw/CVqLReLLu4DpY6sqOKggOlK9xitQZL +lbWbYSMeTZzbt9QM7xVzEdPGSZUmrPw5qpn/S8VPLVVbq8qQ5DHLIzmfkoNiQjmG +revqonJ5nZNL0c+N1UD6uoJrUrUM/D0I43yBog1vEg3SXPvRYQ+ZAUW5cWU869D0 +NfrWJGQxoS8koyCWDRMCAwEAAaNmMGQwHQYDVR0OBBYEFHR9Irf7rVYNu3lt6t3I +54TVTdyRMB8GA1UdIwQYMBaAFClYK2nVOvvQYEahg077qBhbv4N/MBIGA1UdEwEB +/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAd +BAgKyN/Llb8X2OyypuzZtSg4nedDROCS1AO2ZdFdkhQMLqNx443RkhA87wCPOETe +vn2HGvUzqkxu5dVe68XtwnXnR+vPwxOJQHgHKdfVW4MUQFaeRmemnDcJFLoWsvSd +qfYRSd92S8HC57rP4yU7qBjbcRYzP6vswvDyQuj9FP+5ZhXBhlC4ICx3+0JH0OUn +o3Yd0MLXCQJbgDR6hvkZwzn8q4sgNw/QgR4euqgzc53LOyO+dLPUV7zW0Dm9U7O2 +84tEvPcinI48iFBYfeRtGb35I+uTDieth9drb7jLgZYnXFnOc5yAPN07w23Utxfv +Jv6henvJD8inwPsoRUhTvDm8rxAbUKE1kvbdmS+kLOwcGyJx/nmSrakezd7MPk4G +DKtCNND17yTNgP+5SFv2riX6KmwxTd3uoJ4RHW5mWQ9CoPkA5jaUG22yJ2ymqv1/ +z+ga39/T+boyh8cS0SWoc5+Uw8vfEwbzn6HZOAuYxnpkUp1i1oRR8s+LAzNhk3RE +JdveL36N3UgvFz6hQ5WJjwbwIW1Cg6s1s0VweOTIqv2RSO/AnyoNP2tFL6MDwAFN +UKanWzGfnypifLXnlRNxsd7rCyvRD9togIflcJIMiGSJrO45R7zIB0pQZClgOLqz +jkscgOmXw16DHljiV8LjVXI5TldIudtaseRdwi/2wg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0AR918Cv6tCiGvEhw/RXtZJadabLG2YECtTJ3apPi0MU19LK +nHFLxD/Sck2l9os3CZ4pdAUZk3ZW2vKq4vRsmJ85FtXLe9eP0fuP5NP1jFCqT8AF +AB9PyOYwDfSjUsBHTLCr1XE8htoKqdLoWqeGmitEG7oFVxCEkoa8FYFQUwJIzTxC +CHUeztPF6swYkbX+ZbdDwwzIlWwrYSW9oxciirxkoMmgQ+ANTMOHdaKF6AagxGpp +wQLJjEdwnhQbn0YWdxHhC9G/nZg+XwkLyKNynzuo149aquzjNzd80tsWDYQZCmi0 +iiFg3LXjcSsNb8tfmtKREUaF3EGnVKaN7S5xoQIDAQABAoIBAFx1wqHFqevLdGJZ +T9LTprC0LrUgwCKbg6x0zI1UiCq0VG1h6mEDEtRWMepQjTY6xunlfTNumOGstgp3 +1nEuh56HF08JFHslY23ITTs+42PM7wanqRFW2ZXIiw+I75d2k7qIxLgIrwiZnifB +8TlqQTABjzJryrfaRbMDZFKCuftKuSr2GvIaUiCYnX32Z08CaceVQH6k+k2RwaoK +svo2GK5bmQu2S+1orun0/RdGzFDQjk9hp6PTlwpGtCQstwILcZYUz2rLZgi5fvji +/RXXRf9KG1ar05Prt54Bht8X28Wycqc7n5g8Y7chLAXTSGyjLme3kb4FDsVUghND +qRpoCCkCgYEA9EvdhQtpjnGrd/QHNJGNuCAT3AYBS7yFDZqWXTavA4/rNLSIoMDS +9lDroX3ydt74ZpiPKWSFQ9CP4Zi73w6ppy4jwx7ICmslID2JYBZmlTbPpkVLbXl1 +HGgXlQcFIGEB+LtxXaQThrqwgHvN+68/sreMdmbPIEuUwWA//Z+IXtcCgYEA2fuw +xJ1iJKXUSeYSjKsyDr+OfRg8W/mBp5OD2uw/dYEZJnAMIapYt9ZRkgU49voJpcHE +BicinBdzTlCC5tIUQZKo2lAk2yS1hiB/SMTiFZO6rSku+So7i+C+YkxUjgMj7mlz +i2IJvVjVf5TklL/mFD8g1FQtSasC2hw2pbF0fEcCgYAfEsdKdPkoNS0qRM/lz93G +3c2o3tqrV39VC6S0lpAMU/IG8i+uwtgSnJhcIjkFBbdy1VTgXvjUd2LVvyemZ6cM +rMG/v9qR+K7wOuOOZUsHD8G51HaTpi9PPa5CNnJge/ZUPQNeddBGAtkQfq7kpJXl +lZM4PDt8UCDLuAJrsC8YYQKBgQCyfFIrS6r20wnWUJrTr8HXLaZga53QuaYeLr2C +Xns/nauYO5rTXgYy0TwNUlVodSe9H8GAQD8ojFMPxwDIOy/22T2FNKZZAd/YqXdP +gFaW0FXEP7qErr3/NNDu8A00EwIyzwmbEXVkIv797k6UNeUQovggo6RJc8tsCDn+ +xiTZNQKBgQDJyc5NLvY9GSwy4XfhXKc8F2P+FYOSz6di3qf+rGVDu3VSyzwqWKxk +VLAA8I7CoNZlc9+MvVznfr+dptvwpNdI+OmgJq1OES3zjceJ5uvdRKng4+p6Z3rW +Hfjt894+670w9eO8KGOm6kKv8XRUgJHRrAbaWtRR9NpVTheJMl0HnA== +-----END RSA PRIVATE KEY----- diff --git a/test/singlecert.pem b/test/singlecert.pem new file mode 100644 index 0000000..bd23bf4 --- /dev/null +++ b/test/singlecert.pem @@ -0,0 +1,56 @@ +-----BEGIN CERTIFICATE----- +MIIFBDCCAuygAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYUxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtFeGFtcGxlIE9yZzEqMCgG +A1UECwwhRXhhbXBsZSBPcmcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQD +DBZFeGFtcGxlIE9yZyBJc3N1aW5nIENBMB4XDTE4MTAyNDEzMzUyOVoXDTE5MTEw +MzEzMzUyOVowPDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0V4YW1wbGUgT3JnMRcw +FQYDVQQDDA5jbGllbnQuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANAEfdfAr+rQohrxIcP0V7WSWnWmyxtmBArUyd2qT4tDFNfSypxxS8Q/ +0nJNpfaLNwmeKXQFGZN2VtryquL0bJifORbVy3vXj9H7j+TT9YxQqk/ABQAfT8jm +MA30o1LAR0ywq9VxPIbaCqnS6FqnhporRBu6BVcQhJKGvBWBUFMCSM08Qgh1Hs7T +xerMGJG1/mW3Q8MMyJVsK2ElvaMXIoq8ZKDJoEPgDUzDh3WihegGoMRqacECyYxH +cJ4UG59GFncR4QvRv52YPl8JC8ijcp87qNePWqrs4zc3fNLbFg2EGQpotIohYNy1 +43ErDW/LX5rSkRFGhdxBp1Smje0ucaECAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEG +CWCGSAGG+EIBAQQEAwIFoDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0 +ZWQgQ2xpZW50IENlcnRpZmljYXRlMB0GA1UdDgQWBBQC8nA+9cHnnSlSNEJkAOmB +r9rlfDAfBgNVHSMEGDAWgBR0fSK3+61WDbt5berdyOeE1U3ckTAOBgNVHQ8BAf8E +BAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEB +CwUAA4ICAQAKG0Orwjf6q/AdCV+HcYLRDCZuXDHmK6AAYpwo0QUROt5WCTXp71LS +MfTo3HrWnAukhEkyTwpoNQZ7cnWtxnfT1o7Dhl+DTOluc67imRQk4QD8p+vvIsTS +87OHF/94/0rGVWuiBTWX3sDiuV9MKTWn13Fyc1L/btRKM48ax3/P/IeAv8Hrn9PG +mxS/soRkP/VQqAm4E+BjRSkydcd5lnPoSARjVPBuhxL7MpkGIZcJ2IitRtHmSMij +py8LAGa8fHN8OauqimuCvNhlEmq9rDt0YzgbyHTwQdb7p1Kr4lhEs34WBbW0SqEY +KwWkGnJEMbe5CXt04SlkEZs1tKL7M4w05sKqiiDXEg2mxW9U/hEJqW9LK8HUwtd1 +W7o0JPdNC36CUaThRmrQouuaVWd3lltWA2MxTRTriFFci7AefWcKet9xDnVXrvao +mzL0/VGJJLeCV4UEEcAm3h+g0s9cSWfm+bGRoaqcPHKoLJUm6hpJN8PCQeupr0Ix +uCqNojNIjfAPz8NU5bIPOCJxi2BAZaRuIGfOpi2pG0hNDJ3yMkDExHMIGHSxQSTE +l0wHN74JRWVpf7ZD8damp0wvZoFCrXKq6KuR3Vvh1qbKDZZ2DEKi/aNDm6XKvIZc +rHza19g1Ha52SbMuast7BghPxL0JEItyYqVex5jIjY7/UYqFOGhJBQ== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0AR918Cv6tCiGvEhw/RXtZJadabLG2YECtTJ3apPi0MU19LK +nHFLxD/Sck2l9os3CZ4pdAUZk3ZW2vKq4vRsmJ85FtXLe9eP0fuP5NP1jFCqT8AF +AB9PyOYwDfSjUsBHTLCr1XE8htoKqdLoWqeGmitEG7oFVxCEkoa8FYFQUwJIzTxC +CHUeztPF6swYkbX+ZbdDwwzIlWwrYSW9oxciirxkoMmgQ+ANTMOHdaKF6AagxGpp +wQLJjEdwnhQbn0YWdxHhC9G/nZg+XwkLyKNynzuo149aquzjNzd80tsWDYQZCmi0 +iiFg3LXjcSsNb8tfmtKREUaF3EGnVKaN7S5xoQIDAQABAoIBAFx1wqHFqevLdGJZ +T9LTprC0LrUgwCKbg6x0zI1UiCq0VG1h6mEDEtRWMepQjTY6xunlfTNumOGstgp3 +1nEuh56HF08JFHslY23ITTs+42PM7wanqRFW2ZXIiw+I75d2k7qIxLgIrwiZnifB +8TlqQTABjzJryrfaRbMDZFKCuftKuSr2GvIaUiCYnX32Z08CaceVQH6k+k2RwaoK +svo2GK5bmQu2S+1orun0/RdGzFDQjk9hp6PTlwpGtCQstwILcZYUz2rLZgi5fvji +/RXXRf9KG1ar05Prt54Bht8X28Wycqc7n5g8Y7chLAXTSGyjLme3kb4FDsVUghND +qRpoCCkCgYEA9EvdhQtpjnGrd/QHNJGNuCAT3AYBS7yFDZqWXTavA4/rNLSIoMDS +9lDroX3ydt74ZpiPKWSFQ9CP4Zi73w6ppy4jwx7ICmslID2JYBZmlTbPpkVLbXl1 +HGgXlQcFIGEB+LtxXaQThrqwgHvN+68/sreMdmbPIEuUwWA//Z+IXtcCgYEA2fuw +xJ1iJKXUSeYSjKsyDr+OfRg8W/mBp5OD2uw/dYEZJnAMIapYt9ZRkgU49voJpcHE +BicinBdzTlCC5tIUQZKo2lAk2yS1hiB/SMTiFZO6rSku+So7i+C+YkxUjgMj7mlz +i2IJvVjVf5TklL/mFD8g1FQtSasC2hw2pbF0fEcCgYAfEsdKdPkoNS0qRM/lz93G +3c2o3tqrV39VC6S0lpAMU/IG8i+uwtgSnJhcIjkFBbdy1VTgXvjUd2LVvyemZ6cM +rMG/v9qR+K7wOuOOZUsHD8G51HaTpi9PPa5CNnJge/ZUPQNeddBGAtkQfq7kpJXl +lZM4PDt8UCDLuAJrsC8YYQKBgQCyfFIrS6r20wnWUJrTr8HXLaZga53QuaYeLr2C +Xns/nauYO5rTXgYy0TwNUlVodSe9H8GAQD8ojFMPxwDIOy/22T2FNKZZAd/YqXdP +gFaW0FXEP7qErr3/NNDu8A00EwIyzwmbEXVkIv797k6UNeUQovggo6RJc8tsCDn+ +xiTZNQKBgQDJyc5NLvY9GSwy4XfhXKc8F2P+FYOSz6di3qf+rGVDu3VSyzwqWKxk +VLAA8I7CoNZlc9+MvVznfr+dptvwpNdI+OmgJq1OES3zjceJ5uvdRKng4+p6Z3rW +Hfjt894+670w9eO8KGOm6kKv8XRUgJHRrAbaWtRR9NpVTheJMl0HnA== +-----END RSA PRIVATE KEY-----