Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for reading multiple certificates from a PEM file. #142

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"bytes"
"context"
"crypto/tls"
"encoding/pem"
Expand All @@ -22,9 +23,8 @@ import (
"strings"
"time"

"golang.org/x/net/http2"

"github.com/fatih/color"
"golang.org/x/net/http2"
)

const (
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
124 changes: 124 additions & 0 deletions test/multicert.pem
Original file line number Diff line number Diff line change
@@ -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-----
56 changes: 56 additions & 0 deletions test/singlecert.pem
Original file line number Diff line number Diff line change
@@ -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-----