diff --git a/ssl_exporter_test.go b/ssl_exporter_test.go index a5a2fb5..86f3ea9 100644 --- a/ssl_exporter_test.go +++ b/ssl_exporter_test.go @@ -1,7 +1,11 @@ package main import ( + "crypto/tls" + "crypto/x509" + "encoding/pem" "fmt" + "io/ioutil" "net/http" "net/http/httptest" "regexp" @@ -10,29 +14,52 @@ import ( ) func TestProbeHandler(t *testing.T) { + certContent, err := ioutil.ReadFile("test/badssl.com-client.pem") + if err != nil { + t.Fatalf("Can't read test client certificate from disk") + } + + keyContent, err := ioutil.ReadFile("test/badssl.com-client-key.pem") + if err != nil { + t.Fatalf("Can't read test client certificate key from disk") + } + + keyBlock, _ := pem.Decode(keyContent) + + keyBlockDecrypted, err := x509.DecryptPEMBlock(keyBlock, []byte("badssl.com")) + if err != nil { + t.Fatalf("Issue decrypting test client key") + } + + emptyRootCAs := x509.NewCertPool() + + certificate, err := tls.X509KeyPair(certContent, keyBlockDecrypted) // Test the behaviour of various target URIs // 'ok' denotes whether we expect a succesful https connection - // 'insecure' denotes whether we ignore invalid certs cases := []struct { - uri string - ok bool - insecure bool + uri string + ok bool + tlsConfig *tls.Config }{ // Test against an assumed valid, reachable and functioning HTTPS address - {uri: "https://google.com", ok: true, insecure: false}, + {uri: "https://google.com", ok: true, tlsConfig: &tls.Config{}}, // Test against a HTTP address - {uri: "http://google.com", ok: false, insecure: false}, + {uri: "http://google.com", ok: false, tlsConfig: &tls.Config{}}, // Test against an expired certificate when we're rejecting invalid certs - {uri: "https://expired.badssl.com", ok: false, insecure: false}, + {uri: "https://expired.badssl.com", ok: false, tlsConfig: &tls.Config{}}, // Test against an expired certificate when we're accepting invalid certs - {uri: "https://expired.badssl.com", ok: true, insecure: true}, + {uri: "https://expired.badssl.com", ok: true, tlsConfig: &tls.Config{InsecureSkipVerify: true}}, // Test against a target with no protocol - {uri: "google.com", ok: false, insecure: false}, + {uri: "google.com", ok: false, tlsConfig: &tls.Config{}}, // Test against a string with spaces - {uri: "with spaces", ok: false, insecure: false}, + {uri: "with spaces", ok: false, tlsConfig: &tls.Config{}}, // Test against nothing - {uri: "", ok: false, insecure: false}, + {uri: "", ok: false, tlsConfig: &tls.Config{}}, + // Test with client authentication + {uri: "https://client.badssl.com", ok: true, tlsConfig: &tls.Config{Certificates: []tls.Certificate{certificate}}}, + // Test with an empty root CA bundle + {uri: "https://google.com", ok: false, tlsConfig: &tls.Config{RootCAs: emptyRootCAs}}, } fmt.Println("Note: The error logs in these tests are expected. One of the important tests is that we return the expected body, even in the face of errors.") @@ -47,7 +74,7 @@ func TestProbeHandler(t *testing.T) { rr := httptest.NewRecorder() handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - probeHandler(w, r, test.insecure) + probeHandler(w, r, test.tlsConfig) }) handler.ServeHTTP(rr, req) diff --git a/test/badssl.com-client-key.pem b/test/badssl.com-client-key.pem new file mode 100644 index 0000000..39c929d --- /dev/null +++ b/test/badssl.com-client-key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,8906E5B87ECB8682 + +cY/EOwDILOiCPzyqZanlrhrb5h+fCnS/mHhsNme0Zyrk9udaBZKwxkPtUC6rJZ9/ +rX4HQch9tuVy992CDe1bl4l+3EfqshUhxtivG8GHiFj7TNo5Ia9LaE+KwugB2rdX +J8odwWmwE8Y9TX09WyPKHikjg2nAOgN3Gf+GeJW6fL9xcEVmIgDyX6kBusQYWIQ3 +PMYqyaBhL8UCZVRpiUINTrJXCnNAI4t6K0i4J+hjyekRnA5PQ+A/0+C9J+kQW+wj +uDWkQtyyBNsscGhXrL9ita7/UtJa+/aS99FLTnxD+fqyU4svzNIQWmZBcIxb9Lxq +LHcxNaQCtFycD1iU8Tsq9HY1apKrdPBjaaYne6qCg8nIPWpo3gWoffu+R3EfVcdZ +lNgKL3Cd1oCJy/Vcz+u0iayCPT0zfP1dLlGpL2U7L7+8pJ88FbXt/F1th9QEUp5z +dISg/6ukHyIkfXwoxYXkin9fW2clo99+fuXkJaVPEOnRmr0+kf+1S0Uw8fkete4v +f0IUxUwydxCXFN2ZFZ6o/LFLMLRfNAqGSGjqGeY1L0ILkJPo3KBqlmUhl2FIROOW +4rSrfpujjsOqlPncJ9apW04RnqhY7t0YOtp0rMK+gIDteKD+utCyh+UAetiiqTiB +ZDup/kzPNDClSDU6cgRbZUf/Nt8RiBcVeX4TfDb1eEhqV0BTHrLOBo8yp6ETDlJM +CKO5i9kb5fUaFPFD5VTc5rnY4qV/hUj/uyAVK757A+m9nn7fYOMeaRAgOEvChYSf +Qam0VPgpJxfjsaw0BFOMyfsHNJqvTbPXA+hIKD3fhP6jNcgpKTLHJp89J4XUOeIR +tvh/u7vljhVygP7ZQOpCoX1xSMdJMO7Qhrh3O/2fq/EJertJD2PQ0Zgqb8wosHn/ +Aw9VWT6849jL55Xd5l3zXmI9vU0Le4HP3NstV9jjpcp91dU9yfQpcuIo8U26u+4r +LR1VmhZJjo7FBOpyJZ1Jb3vyp+nPI+tH214DhM9LuXvMbf3ORhXTMOlqSABUmo/+ +t+QjVfcEuhFR9CTVWZUIXflJk/euvzqTQdm8iz7JuFzQOhoXjiPIq0GqtCk10SeL +zqHz1s0TZNcrZyzkmiHuWjGVwHN/XZA3dW67uj522hD7EzucKE9CoCdJ3f4JEWmS +CQwEbba6SKAR6iBlouIYLVdkOBgimGiF13rCwvdN234hQeJT8Wc87iG+uDw73PJL ++amDglATH4wIpBk4xmjh/GTRDK0yH9jp7Dv9iwShbjk0yOuoz5yDn8VPqRIREn8d +9sAaiFUUQ/9XrdlA5F+49OznClDWLKHK8sSAAFyrzvoCcqseSKbvLyrlHGT0fiot +obgDu/W+K2xEOjQeaIyVI5J1qOi6k78fyv1vutjEs6mcTRtDAIxi+V5y5lXUEj0v +OWYsbp9yb8Yq602vV8UYSROd+1xdE+7Td3ENLYE7MnVqju7a5NRfnZYgAU03NgIf +nHGFZC6/tMz/PXS+D0dqzXxwEjH5JQzGBjvSQHK09gHtCfcyshMQQWtXZGQViZX8 +QdYXiaq67nJex0DjWTt56a4EgsdYC1J28bJ3GAkrWNkDFRmlx49zvA== +-----END RSA PRIVATE KEY----- diff --git a/test/badssl.com-client.pem b/test/badssl.com-client.pem new file mode 100644 index 0000000..90fb671 --- /dev/null +++ b/test/badssl.com-client.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCAoWgAwIBAgIJAPC7KMFjfslXMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV +BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp +c2NvMQ8wDQYDVQQKDAZCYWRTU0wxMTAvBgNVBAMMKEJhZFNTTCBDbGllbnQgUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTcxMTE2MDUzNjMzWhcNMTkxMTE2 +MDUzNjMzWjBvMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG +A1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0GA1UECgwGQmFkU1NMMSIwIAYDVQQDDBlC +YWRTU0wgQ2xpZW50IENlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxzdfEeseTs/rukjly6MSLHM+Rh0enA3Ai4Mj2sdl31x3SbPoen08 +utVhjPmlxIUdkiMG4+ffe7N+JtDLG75CaxZp9CxytX7kywooRBJsRnQhmQPca8MR +WAJBIz+w/L+3AFkTIqWBfyT+1VO8TVKPkEpGdLDovZOmzZAASi9/sj+j6gM7AaCi +DeZTf2ES66abA5pOp60Q6OEdwg/vCUJfarhKDpi9tj3P6qToy9Y4DiBUhOct4MG8 +w5XwmKAC+Vfm8tb7tMiUoU0yvKKOcL6YXBXxB2kPcOYxYNobXavfVBEdwSrjQ7i/ +s3o6hkGQlm9F7JPEuVgbl/Jdwa64OYIqjQIDAQABoy0wKzAJBgNVHRMEAjAAMBEG +CWCGSAGG+EIBAQQEAwIHgDALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQELBQADggIB +AKpzk1ZTunWuof3DIer2Abq7IV3STGeFaoH4TuHdSbmXwC0KuPkv7wVPgPekyRaH +b9CBnsreRF7eleD1M63kakhdnA1XIbdJw8sfSDlKdI4emmb4fzdaaPxbrkQ5IxOB +QDw5rTUFVPPqFWw1bGP2zrKD1/i1pxUtGM0xem1jR7UZYpsSPs0JCOHKZOmk8OEW +Uy+Jp4gRzbMLZ0TrvajGEZXRepjOkXObR81xZGtvTNP2wl1zm13ffwIYdqJUrf1H +H4miU9lVX+3/Z+2mVHBWhzBgbTmo06s3uwUE6JsxUGm2/w4NNblRit0uQcGw7ba8 +kl2d5rZQscFsqNFz2vRjj1G0dO8S3owmuF0izZO9Fqvq0jB6oaUkxcAcTKFSjs2z +wy1oy+cu8iO3GRbfAW7U0xzGp9MnkdPS5dHzvhod3/DK0YVskfxZF7M8GhkjT7Qm +2EUBQNNMNXC3g/GXTdXOgqqjW5GXahI8Z6Q4OYN6xZwuEhizwKkgojwaww2YgYT9 +MJXciJZWr3QXvFdBH7m0zwpKgQ1wm6j3yeyuRphq2lEtU3OQl55A3tXtvqyMXsxk +xMCCNQdmKQt0WYmMS3Xj/AfAY2sjCWziDflvW5mGCUjSYdZ+r3JIIF4m/FNCIO1d +Ioacp9qb0qL9duFlVHtFiPgoKrEdJaNVUL7NG9ppF8pR +-----END CERTIFICATE-----