aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/lib/pq/ssl_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/lib/pq/ssl_test.go')
-rw-r--r--vendor/github.com/lib/pq/ssl_test.go279
1 files changed, 279 insertions, 0 deletions
diff --git a/vendor/github.com/lib/pq/ssl_test.go b/vendor/github.com/lib/pq/ssl_test.go
new file mode 100644
index 0000000..3eafbfd
--- /dev/null
+++ b/vendor/github.com/lib/pq/ssl_test.go
@@ -0,0 +1,279 @@
+package pq
+
+// This file contains SSL tests
+
+import (
+ _ "crypto/sha256"
+ "crypto/x509"
+ "database/sql"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func maybeSkipSSLTests(t *testing.T) {
+ // Require some special variables for testing certificates
+ if os.Getenv("PQSSLCERTTEST_PATH") == "" {
+ t.Skip("PQSSLCERTTEST_PATH not set, skipping SSL tests")
+ }
+
+ value := os.Getenv("PQGOSSLTESTS")
+ if value == "" || value == "0" {
+ t.Skip("PQGOSSLTESTS not enabled, skipping SSL tests")
+ } else if value != "1" {
+ t.Fatalf("unexpected value %q for PQGOSSLTESTS", value)
+ }
+}
+
+func openSSLConn(t *testing.T, conninfo string) (*sql.DB, error) {
+ db, err := openTestConnConninfo(conninfo)
+ if err != nil {
+ // should never fail
+ t.Fatal(err)
+ }
+ // Do something with the connection to see whether it's working or not.
+ tx, err := db.Begin()
+ if err == nil {
+ return db, tx.Rollback()
+ }
+ _ = db.Close()
+ return nil, err
+}
+
+func checkSSLSetup(t *testing.T, conninfo string) {
+ _, err := openSSLConn(t, conninfo)
+ if pge, ok := err.(*Error); ok {
+ if pge.Code.Name() != "invalid_authorization_specification" {
+ t.Fatalf("unexpected error code '%s'", pge.Code.Name())
+ }
+ } else {
+ t.Fatalf("expected %T, got %v", (*Error)(nil), err)
+ }
+}
+
+// Connect over SSL and run a simple query to test the basics
+func TestSSLConnection(t *testing.T) {
+ maybeSkipSSLTests(t)
+ // Environment sanity check: should fail without SSL
+ checkSSLSetup(t, "sslmode=disable user=pqgossltest")
+
+ db, err := openSSLConn(t, "sslmode=require user=pqgossltest")
+ if err != nil {
+ t.Fatal(err)
+ }
+ rows, err := db.Query("SELECT 1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ rows.Close()
+}
+
+// Test sslmode=verify-full
+func TestSSLVerifyFull(t *testing.T) {
+ maybeSkipSSLTests(t)
+ // Environment sanity check: should fail without SSL
+ checkSSLSetup(t, "sslmode=disable user=pqgossltest")
+
+ // Not OK according to the system CA
+ _, err := openSSLConn(t, "host=postgres sslmode=verify-full user=pqgossltest")
+ if err == nil {
+ t.Fatal("expected error")
+ }
+ _, ok := err.(x509.UnknownAuthorityError)
+ if !ok {
+ t.Fatalf("expected x509.UnknownAuthorityError, got %#+v", err)
+ }
+
+ rootCertPath := filepath.Join(os.Getenv("PQSSLCERTTEST_PATH"), "root.crt")
+ rootCert := "sslrootcert=" + rootCertPath + " "
+ // No match on Common Name
+ _, err = openSSLConn(t, rootCert+"host=127.0.0.1 sslmode=verify-full user=pqgossltest")
+ if err == nil {
+ t.Fatal("expected error")
+ }
+ _, ok = err.(x509.HostnameError)
+ if !ok {
+ t.Fatalf("expected x509.HostnameError, got %#+v", err)
+ }
+ // OK
+ _, err = openSSLConn(t, rootCert+"host=postgres sslmode=verify-full user=pqgossltest")
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+// Test sslmode=require sslrootcert=rootCertPath
+func TestSSLRequireWithRootCert(t *testing.T) {
+ maybeSkipSSLTests(t)
+ // Environment sanity check: should fail without SSL
+ checkSSLSetup(t, "sslmode=disable user=pqgossltest")
+
+ bogusRootCertPath := filepath.Join(os.Getenv("PQSSLCERTTEST_PATH"), "bogus_root.crt")
+ bogusRootCert := "sslrootcert=" + bogusRootCertPath + " "
+
+ // Not OK according to the bogus CA
+ _, err := openSSLConn(t, bogusRootCert+"host=postgres sslmode=require user=pqgossltest")
+ if err == nil {
+ t.Fatal("expected error")
+ }
+ _, ok := err.(x509.UnknownAuthorityError)
+ if !ok {
+ t.Fatalf("expected x509.UnknownAuthorityError, got %s, %#+v", err, err)
+ }
+
+ nonExistentCertPath := filepath.Join(os.Getenv("PQSSLCERTTEST_PATH"), "non_existent.crt")
+ nonExistentCert := "sslrootcert=" + nonExistentCertPath + " "
+
+ // No match on Common Name, but that's OK because we're not validating anything.
+ _, err = openSSLConn(t, nonExistentCert+"host=127.0.0.1 sslmode=require user=pqgossltest")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ rootCertPath := filepath.Join(os.Getenv("PQSSLCERTTEST_PATH"), "root.crt")
+ rootCert := "sslrootcert=" + rootCertPath + " "
+
+ // No match on Common Name, but that's OK because we're not validating the CN.
+ _, err = openSSLConn(t, rootCert+"host=127.0.0.1 sslmode=require user=pqgossltest")
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Everything OK
+ _, err = openSSLConn(t, rootCert+"host=postgres sslmode=require user=pqgossltest")
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+// Test sslmode=verify-ca
+func TestSSLVerifyCA(t *testing.T) {
+ maybeSkipSSLTests(t)
+ // Environment sanity check: should fail without SSL
+ checkSSLSetup(t, "sslmode=disable user=pqgossltest")
+
+ // Not OK according to the system CA
+ {
+ _, err := openSSLConn(t, "host=postgres sslmode=verify-ca user=pqgossltest")
+ if _, ok := err.(x509.UnknownAuthorityError); !ok {
+ t.Fatalf("expected %T, got %#+v", x509.UnknownAuthorityError{}, err)
+ }
+ }
+
+ // Still not OK according to the system CA; empty sslrootcert is treated as unspecified.
+ {
+ _, err := openSSLConn(t, "host=postgres sslmode=verify-ca user=pqgossltest sslrootcert=''")
+ if _, ok := err.(x509.UnknownAuthorityError); !ok {
+ t.Fatalf("expected %T, got %#+v", x509.UnknownAuthorityError{}, err)
+ }
+ }
+
+ rootCertPath := filepath.Join(os.Getenv("PQSSLCERTTEST_PATH"), "root.crt")
+ rootCert := "sslrootcert=" + rootCertPath + " "
+ // No match on Common Name, but that's OK
+ if _, err := openSSLConn(t, rootCert+"host=127.0.0.1 sslmode=verify-ca user=pqgossltest"); err != nil {
+ t.Fatal(err)
+ }
+ // Everything OK
+ if _, err := openSSLConn(t, rootCert+"host=postgres sslmode=verify-ca user=pqgossltest"); err != nil {
+ t.Fatal(err)
+ }
+}
+
+// Authenticate over SSL using client certificates
+func TestSSLClientCertificates(t *testing.T) {
+ maybeSkipSSLTests(t)
+ // Environment sanity check: should fail without SSL
+ checkSSLSetup(t, "sslmode=disable user=pqgossltest")
+
+ const baseinfo = "sslmode=require user=pqgosslcert"
+
+ // Certificate not specified, should fail
+ {
+ _, err := openSSLConn(t, baseinfo)
+ if pge, ok := err.(*Error); ok {
+ if pge.Code.Name() != "invalid_authorization_specification" {
+ t.Fatalf("unexpected error code '%s'", pge.Code.Name())
+ }
+ } else {
+ t.Fatalf("expected %T, got %v", (*Error)(nil), err)
+ }
+ }
+
+ // Empty certificate specified, should fail
+ {
+ _, err := openSSLConn(t, baseinfo+" sslcert=''")
+ if pge, ok := err.(*Error); ok {
+ if pge.Code.Name() != "invalid_authorization_specification" {
+ t.Fatalf("unexpected error code '%s'", pge.Code.Name())
+ }
+ } else {
+ t.Fatalf("expected %T, got %v", (*Error)(nil), err)
+ }
+ }
+
+ // Non-existent certificate specified, should fail
+ {
+ _, err := openSSLConn(t, baseinfo+" sslcert=/tmp/filedoesnotexist")
+ if pge, ok := err.(*Error); ok {
+ if pge.Code.Name() != "invalid_authorization_specification" {
+ t.Fatalf("unexpected error code '%s'", pge.Code.Name())
+ }
+ } else {
+ t.Fatalf("expected %T, got %v", (*Error)(nil), err)
+ }
+ }
+
+ certpath, ok := os.LookupEnv("PQSSLCERTTEST_PATH")
+ if !ok {
+ t.Fatalf("PQSSLCERTTEST_PATH not present in environment")
+ }
+
+ sslcert := filepath.Join(certpath, "postgresql.crt")
+
+ // Cert present, key not specified, should fail
+ {
+ _, err := openSSLConn(t, baseinfo+" sslcert="+sslcert)
+ if _, ok := err.(*os.PathError); !ok {
+ t.Fatalf("expected %T, got %#+v", (*os.PathError)(nil), err)
+ }
+ }
+
+ // Cert present, empty key specified, should fail
+ {
+ _, err := openSSLConn(t, baseinfo+" sslcert="+sslcert+" sslkey=''")
+ if _, ok := err.(*os.PathError); !ok {
+ t.Fatalf("expected %T, got %#+v", (*os.PathError)(nil), err)
+ }
+ }
+
+ // Cert present, non-existent key, should fail
+ {
+ _, err := openSSLConn(t, baseinfo+" sslcert="+sslcert+" sslkey=/tmp/filedoesnotexist")
+ if _, ok := err.(*os.PathError); !ok {
+ t.Fatalf("expected %T, got %#+v", (*os.PathError)(nil), err)
+ }
+ }
+
+ // Key has wrong permissions (passing the cert as the key), should fail
+ if _, err := openSSLConn(t, baseinfo+" sslcert="+sslcert+" sslkey="+sslcert); err != ErrSSLKeyHasWorldPermissions {
+ t.Fatalf("expected %s, got %#+v", ErrSSLKeyHasWorldPermissions, err)
+ }
+
+ sslkey := filepath.Join(certpath, "postgresql.key")
+
+ // Should work
+ if db, err := openSSLConn(t, baseinfo+" sslcert="+sslcert+" sslkey="+sslkey); err != nil {
+ t.Fatal(err)
+ } else {
+ rows, err := db.Query("SELECT 1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := rows.Close(); err != nil {
+ t.Fatal(err)
+ }
+ if err := db.Close(); err != nil {
+ t.Fatal(err)
+ }
+ }
+}