github.com/snowflakedb/gosnowflake@v1.9.0/driver_ocsp_test.go (about)

     1  // Copyright (c) 2019-2022 Snowflake Computing Inc. All rights reserved.
     2  
     3  package gosnowflake
     4  
     5  import (
     6  	"crypto/x509"
     7  	"database/sql"
     8  	"net/url"
     9  	"os"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func setenv(k, v string) {
    16  	err := os.Setenv(k, v)
    17  	if err != nil {
    18  		panic(err)
    19  	}
    20  }
    21  
    22  func unsetenv(k string) {
    23  	err := os.Unsetenv(k)
    24  	if err != nil {
    25  		panic(err)
    26  	}
    27  }
    28  
    29  // deleteOCSPCacheFile deletes the OCSP response cache file
    30  func deleteOCSPCacheFile() {
    31  	os.Remove(cacheFileName)
    32  }
    33  
    34  // deleteOCSPCacheAll deletes all entries in the OCSP response cache on memory
    35  func deleteOCSPCacheAll() {
    36  	ocspResponseCacheLock.Lock()
    37  	defer ocspResponseCacheLock.Unlock()
    38  	ocspResponseCache = make(map[certIDKey]*certCacheValue)
    39  }
    40  
    41  func cleanup() {
    42  	deleteOCSPCacheFile()
    43  	deleteOCSPCacheAll()
    44  	setenv(cacheServerEnabledEnv, "true")
    45  	unsetenv(ocspTestInjectValidityErrorEnv)
    46  	unsetenv(ocspTestInjectUnknownStatusEnv)
    47  	unsetenv(cacheServerURLEnv)
    48  	unsetenv(ocspTestResponseCacheServerTimeoutEnv)
    49  	unsetenv(ocspTestResponderTimeoutEnv)
    50  	unsetenv(ocspTestResponderURLEnv)
    51  	unsetenv(ocspTestNoOCSPURLEnv)
    52  	unsetenv(ocspRetryURLEnv)
    53  	unsetenv(cacheDirEnv)
    54  }
    55  
    56  // TestOCSPFailOpen just confirms OCSPFailOpenTrue works.
    57  func TestOCSPFailOpen(t *testing.T) {
    58  	cleanup()
    59  	defer cleanup()
    60  
    61  	config := &Config{
    62  		Account:      "fakeaccount1",
    63  		User:         "fakeuser",
    64  		Password:     "fakepassword",
    65  		LoginTimeout: 10 * time.Second,
    66  		OCSPFailOpen: OCSPFailOpenTrue,
    67  	}
    68  	var db *sql.DB
    69  	var err error
    70  	var testURL string
    71  	testURL, err = DSN(config)
    72  	if err != nil {
    73  		t.Fatalf("failed to build URL from Config: %v", config)
    74  	}
    75  
    76  	if db, err = sql.Open("snowflake", testURL); err != nil {
    77  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
    78  	}
    79  	defer db.Close()
    80  	if err = db.Ping(); err == nil {
    81  		t.Fatalf("should fail to ping. %v", testURL)
    82  	}
    83  	driverErr, ok := err.(*SnowflakeError)
    84  	if !ok {
    85  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
    86  	}
    87  	if driverErr.Number != ErrCodeFailedToConnect {
    88  		t.Fatalf("should failed to connect %v", err)
    89  	}
    90  }
    91  
    92  // TestOCSPFailOpenWithoutFileCache ensures no file cache is used.
    93  func TestOCSPFailOpenWithoutFileCache(t *testing.T) {
    94  	cleanup()
    95  	defer cleanup()
    96  
    97  	setenv(cacheDirEnv, "/NEVER_EXISTS")
    98  
    99  	config := &Config{
   100  		Account:      "fakeaccount1",
   101  		User:         "fakeuser",
   102  		Password:     "fakepassword",
   103  		LoginTimeout: 10 * time.Second,
   104  		OCSPFailOpen: OCSPFailOpenTrue,
   105  	}
   106  	var db *sql.DB
   107  	var err error
   108  	var testURL string
   109  	testURL, err = DSN(config)
   110  	if err != nil {
   111  		t.Fatalf("failed to build URL from Config: %v", config)
   112  	}
   113  
   114  	if db, err = sql.Open("snowflake", testURL); err != nil {
   115  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   116  	}
   117  	defer db.Close()
   118  	if err = db.Ping(); err == nil {
   119  		t.Fatalf("should fail to ping. %v", testURL)
   120  	}
   121  	driverErr, ok := err.(*SnowflakeError)
   122  	if !ok {
   123  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   124  	}
   125  	if driverErr.Number != ErrCodeFailedToConnect {
   126  		t.Fatalf("should failed to connect %v", err)
   127  	}
   128  }
   129  
   130  // TestOCSPFailOpenValidityError tests Validity error.
   131  func TestOCSPFailOpenValidityError(t *testing.T) {
   132  	cleanup()
   133  	defer cleanup()
   134  
   135  	setenv(cacheServerEnabledEnv, "false")
   136  	setenv(ocspTestInjectValidityErrorEnv, "true")
   137  
   138  	config := &Config{
   139  		Account:      "fakeaccount2",
   140  		User:         "fakeuser",
   141  		Password:     "fakepassword",
   142  		LoginTimeout: 10 * time.Second,
   143  		OCSPFailOpen: OCSPFailOpenTrue,
   144  	}
   145  	var db *sql.DB
   146  	var err error
   147  	var testURL string
   148  	testURL, err = DSN(config)
   149  	if err != nil {
   150  		t.Fatalf("failed to build URL from Config: %v", config)
   151  	}
   152  
   153  	if db, err = sql.Open("snowflake", testURL); err != nil {
   154  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   155  	}
   156  	defer db.Close()
   157  	if err = db.Ping(); err == nil {
   158  		t.Fatalf("should fail to ping. %v", testURL)
   159  	}
   160  	driverErr, ok := err.(*SnowflakeError)
   161  	if !ok {
   162  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   163  	}
   164  	if driverErr.Number != ErrCodeFailedToConnect {
   165  		t.Fatalf("should failed to connect %v", err)
   166  	}
   167  }
   168  
   169  // TestOCSPFailClosedValidityError tests Validity error. Fail Closed mode should propagate it.
   170  func TestOCSPFailClosedValidityError(t *testing.T) {
   171  	cleanup()
   172  	defer cleanup()
   173  
   174  	setenv(cacheServerEnabledEnv, "false")
   175  	setenv(ocspTestInjectValidityErrorEnv, "true")
   176  
   177  	config := &Config{
   178  		Account:      "fakeaccount3",
   179  		User:         "fakeuser",
   180  		Password:     "fakepassword",
   181  		LoginTimeout: 20 * time.Second,
   182  		OCSPFailOpen: OCSPFailOpenFalse,
   183  	}
   184  	var db *sql.DB
   185  	var err error
   186  	var testURL string
   187  	testURL, err = DSN(config)
   188  	if err != nil {
   189  		t.Fatalf("failed to build URL from Config: %v", config)
   190  	}
   191  
   192  	if db, err = sql.Open("snowflake", testURL); err != nil {
   193  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   194  	}
   195  	defer db.Close()
   196  	if err = db.Ping(); err == nil {
   197  		t.Fatalf("should fail to ping. %v", testURL)
   198  	}
   199  	urlErr, ok := err.(*url.Error)
   200  	if !ok {
   201  		t.Fatalf("failed to extract error URL Error: %v", err)
   202  	}
   203  	var driverErr *SnowflakeError
   204  	driverErr, ok = urlErr.Err.(*SnowflakeError)
   205  	if !ok {
   206  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   207  	}
   208  	if driverErr.Number != ErrOCSPInvalidValidity {
   209  		t.Fatalf("should failed to connect %v", err)
   210  	}
   211  }
   212  
   213  // TestOCSPFailOpenUnknownStatus tests Validity error.
   214  func TestOCSPFailOpenUnknownStatus(t *testing.T) {
   215  	cleanup()
   216  	defer cleanup()
   217  
   218  	setenv(cacheServerEnabledEnv, "false")
   219  	setenv(ocspTestInjectUnknownStatusEnv, "true")
   220  
   221  	config := &Config{
   222  		Account:      "fakeaccount4",
   223  		User:         "fakeuser",
   224  		Password:     "fakepassword",
   225  		LoginTimeout: 10 * time.Second,
   226  		OCSPFailOpen: OCSPFailOpenTrue,
   227  	}
   228  	var db *sql.DB
   229  	var err error
   230  	var testURL string
   231  	testURL, err = DSN(config)
   232  	if err != nil {
   233  		t.Fatalf("failed to build URL from Config: %v", config)
   234  	}
   235  
   236  	if db, err = sql.Open("snowflake", testURL); err != nil {
   237  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   238  	}
   239  	defer db.Close()
   240  	if err = db.Ping(); err == nil {
   241  		t.Fatalf("should fail to ping. %v", testURL)
   242  	}
   243  	driverErr, ok := err.(*SnowflakeError)
   244  	if !ok {
   245  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   246  	}
   247  	if driverErr.Number != ErrCodeFailedToConnect {
   248  		t.Fatalf("should failed to connect %v", err)
   249  	}
   250  }
   251  
   252  // TestOCSPFailClosedUnknownStatus tests Validity error
   253  func TestOCSPFailClosedUnknownStatus(t *testing.T) {
   254  	cleanup()
   255  	defer cleanup()
   256  
   257  	setenv(cacheServerEnabledEnv, "false")
   258  	setenv(ocspTestInjectUnknownStatusEnv, "true")
   259  
   260  	config := &Config{
   261  		Account:      "fakeaccount5",
   262  		User:         "fakeuser",
   263  		Password:     "fakepassword",
   264  		LoginTimeout: 20 * time.Second,
   265  		OCSPFailOpen: OCSPFailOpenFalse,
   266  	}
   267  	var db *sql.DB
   268  	var err error
   269  	var testURL string
   270  	testURL, err = DSN(config)
   271  	if err != nil {
   272  		t.Fatalf("failed to build URL from Config: %v", config)
   273  	}
   274  
   275  	if db, err = sql.Open("snowflake", testURL); err != nil {
   276  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   277  	}
   278  	defer db.Close()
   279  	if err = db.Ping(); err == nil {
   280  		t.Fatalf("should fail to ping. %v", testURL)
   281  	}
   282  	urlErr, ok := err.(*url.Error)
   283  	if !ok {
   284  		t.Fatalf("failed to extract error URL Error: %v", err)
   285  	}
   286  	var driverErr *SnowflakeError
   287  	driverErr, ok = urlErr.Err.(*SnowflakeError)
   288  	if !ok {
   289  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   290  	}
   291  	if driverErr.Number != ErrOCSPStatusUnknown {
   292  		t.Fatalf("should failed to connect %v", err)
   293  	}
   294  }
   295  
   296  // TestOCSPFailOpenRevokedStatus tests revoked certificate.
   297  func TestOCSPFailOpenRevokedStatus(t *testing.T) {
   298  	t.Skip("revoked.badssl.com certificate expired")
   299  	cleanup()
   300  	defer cleanup()
   301  
   302  	setenv(cacheServerEnabledEnv, "false")
   303  
   304  	config := &Config{
   305  		Account:      "fakeaccount6",
   306  		User:         "fakeuser",
   307  		Password:     "fakepassword",
   308  		Host:         "revoked.badssl.com",
   309  		LoginTimeout: 10 * time.Second,
   310  		OCSPFailOpen: OCSPFailOpenTrue,
   311  	}
   312  	var db *sql.DB
   313  	var err error
   314  	var testURL string
   315  	testURL, err = DSN(config)
   316  	if err != nil {
   317  		t.Fatalf("failed to build URL from Config: %v", config)
   318  	}
   319  
   320  	if db, err = sql.Open("snowflake", testURL); err != nil {
   321  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   322  	}
   323  	defer db.Close()
   324  	if err = db.Ping(); err == nil {
   325  		t.Fatalf("should fail to ping. %v", testURL)
   326  	}
   327  	urlErr, ok := err.(*url.Error)
   328  	if !ok {
   329  		t.Fatalf("failed to extract error URL Error: %v", err)
   330  	}
   331  	var driverErr *SnowflakeError
   332  	driverErr, ok = urlErr.Err.(*SnowflakeError)
   333  	if !ok {
   334  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   335  	}
   336  	if driverErr.Number != ErrOCSPStatusRevoked {
   337  		t.Fatalf("should failed to connect %v", err)
   338  	}
   339  }
   340  
   341  // TestOCSPFailClosedRevokedStatus tests revoked Certificate.
   342  func TestOCSPFailClosedRevokedStatus(t *testing.T) {
   343  	t.Skip("revoked.badssl.com certificate expired")
   344  	cleanup()
   345  	defer cleanup()
   346  
   347  	setenv(cacheServerEnabledEnv, "false")
   348  
   349  	config := &Config{
   350  		Account:      "fakeaccount7",
   351  		User:         "fakeuser",
   352  		Password:     "fakepassword",
   353  		Host:         "revoked.badssl.com",
   354  		LoginTimeout: 20 * time.Second,
   355  		OCSPFailOpen: OCSPFailOpenFalse,
   356  	}
   357  	var db *sql.DB
   358  	var err error
   359  	var testURL string
   360  	testURL, err = DSN(config)
   361  	if err != nil {
   362  		t.Fatalf("failed to build URL from Config: %v", config)
   363  	}
   364  
   365  	if db, err = sql.Open("snowflake", testURL); err != nil {
   366  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   367  	}
   368  	defer db.Close()
   369  	if err = db.Ping(); err == nil {
   370  		t.Fatalf("should fail to ping. %v", testURL)
   371  	}
   372  	urlErr, ok := err.(*url.Error)
   373  	if !ok {
   374  		t.Fatalf("failed to extract error URL Error: %v", err)
   375  	}
   376  	var driverErr *SnowflakeError
   377  	driverErr, ok = urlErr.Err.(*SnowflakeError)
   378  	if !ok {
   379  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   380  	}
   381  	if driverErr.Number != ErrOCSPStatusRevoked {
   382  		t.Fatalf("should failed to connect %v", err)
   383  	}
   384  }
   385  
   386  // TestOCSPFailOpenCacheServerTimeout tests OCSP Cache server timeout.
   387  func TestOCSPFailOpenCacheServerTimeout(t *testing.T) {
   388  	cleanup()
   389  	defer cleanup()
   390  
   391  	setenv(cacheServerURLEnv, "http://localhost:12345/ocsp/hang")
   392  	setenv(ocspTestResponseCacheServerTimeoutEnv, "1000")
   393  
   394  	config := &Config{
   395  		Account:      "fakeaccount8",
   396  		User:         "fakeuser",
   397  		Password:     "fakepassword",
   398  		LoginTimeout: 10 * time.Second,
   399  		OCSPFailOpen: OCSPFailOpenTrue,
   400  	}
   401  	var db *sql.DB
   402  	var err error
   403  	var testURL string
   404  	testURL, err = DSN(config)
   405  	if err != nil {
   406  		t.Fatalf("failed to build URL from Config: %v", config)
   407  	}
   408  
   409  	if db, err = sql.Open("snowflake", testURL); err != nil {
   410  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   411  	}
   412  	defer db.Close()
   413  	if err = db.Ping(); err == nil {
   414  		t.Fatalf("should fail to ping. %v", testURL)
   415  	}
   416  	driverErr, ok := err.(*SnowflakeError)
   417  	if !ok {
   418  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   419  	}
   420  	if driverErr.Number != ErrCodeFailedToConnect {
   421  		t.Fatalf("should failed to connect %v", err)
   422  	}
   423  }
   424  
   425  // TestOCSPFailClosedCacheServerTimeout tests OCSP Cache Server timeout
   426  func TestOCSPFailClosedCacheServerTimeout(t *testing.T) {
   427  	cleanup()
   428  	defer cleanup()
   429  
   430  	setenv(cacheServerURLEnv, "http://localhost:12345/ocsp/hang")
   431  	setenv(ocspTestResponseCacheServerTimeoutEnv, "1000")
   432  
   433  	config := &Config{
   434  		Account:      "fakeaccount9",
   435  		User:         "fakeuser",
   436  		Password:     "fakepassword",
   437  		LoginTimeout: 20 * time.Second,
   438  		OCSPFailOpen: OCSPFailOpenFalse,
   439  	}
   440  	var db *sql.DB
   441  	var err error
   442  	var testURL string
   443  	testURL, err = DSN(config)
   444  	if err != nil {
   445  		t.Fatalf("failed to build URL from Config: %v", config)
   446  	}
   447  
   448  	if db, err = sql.Open("snowflake", testURL); err != nil {
   449  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   450  	}
   451  	defer db.Close()
   452  	if err = db.Ping(); err == nil {
   453  		t.Fatalf("should fail to ping. %v", testURL)
   454  	}
   455  	if err == nil {
   456  		t.Fatalf("should failed to connect. err:  %v", err)
   457  	}
   458  
   459  	switch errType := err.(type) {
   460  	// Before Go 1.17
   461  	case *SnowflakeError:
   462  		driverErr, ok := err.(*SnowflakeError)
   463  		if !ok {
   464  			t.Fatalf("failed to extract error SnowflakeError: %v", err)
   465  		}
   466  		if driverErr.Number != ErrCodeFailedToConnect {
   467  			t.Fatalf("should have failed to connect. err: %v", err)
   468  		}
   469  	// Go 1.18 and after rejects SHA-1 certificates, therefore a different error is returned (https://github.com/golang/go/issues/41682)
   470  	case *url.Error:
   471  		expectedErrMsg := "bad OCSP signature"
   472  		if !strings.Contains(err.Error(), expectedErrMsg) {
   473  			t.Fatalf("should have failed with bad OCSP signature. err:  %v", err)
   474  		}
   475  	default:
   476  		t.Fatalf("should failed to connect. err type: %v, err:  %v", errType, err)
   477  	}
   478  }
   479  
   480  // TestOCSPFailOpenResponderTimeout tests OCSP Responder timeout.
   481  func TestOCSPFailOpenResponderTimeout(t *testing.T) {
   482  	cleanup()
   483  	defer cleanup()
   484  
   485  	setenv(cacheServerEnabledEnv, "false")
   486  	setenv(ocspTestResponderURLEnv, "http://localhost:12345/ocsp/hang")
   487  	setenv(ocspTestResponderTimeoutEnv, "1000")
   488  
   489  	config := &Config{
   490  		Account:      "fakeaccount10",
   491  		User:         "fakeuser",
   492  		Password:     "fakepassword",
   493  		LoginTimeout: 10 * time.Second,
   494  		OCSPFailOpen: OCSPFailOpenTrue,
   495  	}
   496  	var db *sql.DB
   497  	var err error
   498  	var testURL string
   499  	testURL, err = DSN(config)
   500  	if err != nil {
   501  		t.Fatalf("failed to build URL from Config: %v", config)
   502  	}
   503  
   504  	if db, err = sql.Open("snowflake", testURL); err != nil {
   505  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   506  	}
   507  	defer db.Close()
   508  	if err = db.Ping(); err == nil {
   509  		t.Fatalf("should fail to ping. %v", testURL)
   510  	}
   511  	driverErr, ok := err.(*SnowflakeError)
   512  	if !ok {
   513  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   514  	}
   515  	if driverErr.Number != ErrCodeFailedToConnect {
   516  		t.Fatalf("should failed to connect %v", err)
   517  	}
   518  }
   519  
   520  // TestOCSPFailClosedResponderTimeout tests OCSP Responder timeout
   521  func TestOCSPFailClosedResponderTimeout(t *testing.T) {
   522  	cleanup()
   523  	defer cleanup()
   524  
   525  	setenv(cacheServerEnabledEnv, "false")
   526  	setenv(ocspTestResponderURLEnv, "http://localhost:12345/ocsp/hang")
   527  	setenv(ocspTestResponderTimeoutEnv, "1000")
   528  
   529  	config := &Config{
   530  		Account:      "fakeaccount11",
   531  		User:         "fakeuser",
   532  		Password:     "fakepassword",
   533  		LoginTimeout: 20 * time.Second,
   534  		OCSPFailOpen: OCSPFailOpenFalse,
   535  	}
   536  	var db *sql.DB
   537  	var err error
   538  	var testURL string
   539  	testURL, err = DSN(config)
   540  	if err != nil {
   541  		t.Fatalf("failed to build URL from Config: %v", config)
   542  	}
   543  
   544  	if db, err = sql.Open("snowflake", testURL); err != nil {
   545  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   546  	}
   547  	defer db.Close()
   548  	if err = db.Ping(); err == nil {
   549  		t.Fatalf("should fail to ping. %v", testURL)
   550  	}
   551  	urlErr, ok := err.(*url.Error)
   552  	if !ok {
   553  		t.Fatalf("failed to extract error URL Error: %v", err)
   554  	}
   555  	urlErr0, ok := urlErr.Err.(*url.Error)
   556  	if !ok {
   557  		t.Fatalf("failed to extract error URL Error: %v", urlErr.Err)
   558  	}
   559  	if !strings.Contains(urlErr0.Err.Error(), "Client.Timeout") {
   560  		t.Fatalf("the root cause is not  timeout: %v", urlErr0.Err)
   561  	}
   562  }
   563  
   564  // TestOCSPFailOpenResponder404 tests OCSP Responder HTTP 404
   565  func TestOCSPFailOpenResponder404(t *testing.T) {
   566  	cleanup()
   567  	defer cleanup()
   568  
   569  	setenv(cacheServerEnabledEnv, "false")
   570  	setenv(ocspTestResponderURLEnv, "http://localhost:12345/ocsp/404")
   571  
   572  	config := &Config{
   573  		Account:      "fakeaccount10",
   574  		User:         "fakeuser",
   575  		Password:     "fakepassword",
   576  		LoginTimeout: 10 * time.Second,
   577  		OCSPFailOpen: OCSPFailOpenTrue,
   578  	}
   579  	var db *sql.DB
   580  	var err error
   581  	var testURL string
   582  	testURL, err = DSN(config)
   583  	if err != nil {
   584  		t.Fatalf("failed to build URL from Config: %v", config)
   585  	}
   586  
   587  	if db, err = sql.Open("snowflake", testURL); err != nil {
   588  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   589  	}
   590  	defer db.Close()
   591  	if err = db.Ping(); err == nil {
   592  		t.Fatalf("should fail to ping. %v", testURL)
   593  	}
   594  	driverErr, ok := err.(*SnowflakeError)
   595  	if !ok {
   596  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   597  	}
   598  	if driverErr.Number != ErrCodeFailedToConnect {
   599  		t.Fatalf("should failed to connect %v", err)
   600  	}
   601  }
   602  
   603  // TestOCSPFailClosedResponder404 tests OCSP Responder HTTP 404
   604  func TestOCSPFailClosedResponder404(t *testing.T) {
   605  	cleanup()
   606  	defer cleanup()
   607  
   608  	setenv(cacheServerEnabledEnv, "false")
   609  	setenv(ocspTestResponderURLEnv, "http://localhost:12345/ocsp/404")
   610  
   611  	config := &Config{
   612  		Account:      "fakeaccount11",
   613  		User:         "fakeuser",
   614  		Password:     "fakepassword",
   615  		LoginTimeout: 20 * time.Second,
   616  		OCSPFailOpen: OCSPFailOpenFalse,
   617  	}
   618  	var db *sql.DB
   619  	var err error
   620  	var testURL string
   621  	testURL, err = DSN(config)
   622  	if err != nil {
   623  		t.Fatalf("failed to build URL from Config: %v", config)
   624  	}
   625  
   626  	if db, err = sql.Open("snowflake", testURL); err != nil {
   627  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   628  	}
   629  	defer db.Close()
   630  	if err = db.Ping(); err == nil {
   631  		t.Fatalf("should fail to ping. %v", testURL)
   632  	}
   633  	urlErr, ok := err.(*url.Error)
   634  	if !ok {
   635  		t.Fatalf("failed to extract error URL Error: %v", err)
   636  	}
   637  	if !strings.Contains(urlErr.Err.Error(), "404 Not Found") {
   638  		t.Fatalf("the root cause is not timeout: %v", urlErr.Err)
   639  	}
   640  }
   641  
   642  // TestExpiredCertificate tests expired certificate
   643  func TestExpiredCertificate(t *testing.T) {
   644  	cleanup()
   645  	defer cleanup()
   646  
   647  	config := &Config{
   648  		Account:      "fakeaccount10",
   649  		User:         "fakeuser",
   650  		Password:     "fakepassword",
   651  		Host:         "expired.badssl.com",
   652  		LoginTimeout: 10 * time.Second,
   653  		OCSPFailOpen: OCSPFailOpenTrue,
   654  	}
   655  	var db *sql.DB
   656  	var err error
   657  	var testURL string
   658  	testURL, err = DSN(config)
   659  	if err != nil {
   660  		t.Fatalf("failed to build URL from Config: %v", config)
   661  	}
   662  
   663  	if db, err = sql.Open("snowflake", testURL); err != nil {
   664  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   665  	}
   666  	defer db.Close()
   667  	if err = db.Ping(); err == nil {
   668  		t.Fatalf("should fail to ping. %v", testURL)
   669  	}
   670  	urlErr, ok := err.(*url.Error)
   671  	if !ok {
   672  		t.Fatalf("failed to extract error URL Error: %v", err)
   673  	}
   674  	_, ok = urlErr.Err.(x509.CertificateInvalidError)
   675  
   676  	if !ok {
   677  		// Go 1.20 throws tls CertificateVerification error
   678  		errString := urlErr.Err.Error()
   679  		if !strings.Contains(errString, "certificate has expired or is not yet valid") {
   680  			t.Fatalf("failed to extract error Certificate error: %v", err)
   681  		}
   682  	}
   683  }
   684  
   685  /*
   686  DISABLED: sicne it appeared self-signed.badssl.com is not well maintained,
   687            this test is no longer reliable.
   688  // TestSelfSignedCertificate tests self-signed certificate
   689  func TestSelfSignedCertificate(t *testing.T) {
   690  	cleanup()
   691  	defer cleanup()
   692  
   693  	config := &Config{
   694  		Account:      "fakeaccount10",
   695  		User:         "fakeuser",
   696  		Password:     "fakepassword",
   697  		Host:         "self-signed.badssl.com",
   698  		LoginTimeout: 10 * time.Second,
   699  		OCSPFailOpen: OCSPFailOpenTrue,
   700  	}
   701  	var db *sql.DB
   702  	var err error
   703  	var testURL string
   704  	testURL, err = DSN(config)
   705  	if err != nil {
   706  		t.Fatalf("failed to build URL from Config: %v", config)
   707  	}
   708  
   709  	if db, err = sql.Open("snowflake", testURL); err != nil {
   710  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   711  	}
   712  	defer db.Close()
   713  	if err = db.Ping(); err == nil {
   714  		t.Fatalf("should fail to ping. %v", testURL)
   715  	}
   716  	urlErr, ok := err.(*url.Error)
   717  	if !ok {
   718  		t.Fatalf("failed to extract error URL Error: %v", err)
   719  	}
   720  	_, ok = urlErr.Err.(x509.UnknownAuthorityError)
   721  	if !ok {
   722  		t.Fatalf("failed to extract error Certificate error: %v", err)
   723  	}
   724  }
   725  */
   726  
   727  // TestOCSPFailOpenNoOCSPURL tests no OCSP URL
   728  func TestOCSPFailOpenNoOCSPURL(t *testing.T) {
   729  	cleanup()
   730  	defer cleanup()
   731  
   732  	setenv(cacheServerEnabledEnv, "false")
   733  	setenv(ocspTestNoOCSPURLEnv, "true")
   734  
   735  	config := &Config{
   736  		Account:      "fakeaccount10",
   737  		User:         "fakeuser",
   738  		Password:     "fakepassword",
   739  		LoginTimeout: 10 * time.Second,
   740  		OCSPFailOpen: OCSPFailOpenTrue,
   741  	}
   742  	var db *sql.DB
   743  	var err error
   744  	var testURL string
   745  	testURL, err = DSN(config)
   746  	if err != nil {
   747  		t.Fatalf("failed to build URL from Config: %v", config)
   748  	}
   749  
   750  	if db, err = sql.Open("snowflake", testURL); err != nil {
   751  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   752  	}
   753  	defer db.Close()
   754  	if err = db.Ping(); err == nil {
   755  		t.Fatalf("should fail to ping. %v", testURL)
   756  	}
   757  	driverErr, ok := err.(*SnowflakeError)
   758  	if !ok {
   759  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   760  	}
   761  	if driverErr.Number != ErrCodeFailedToConnect {
   762  		t.Fatalf("should failed to connect %v", err)
   763  	}
   764  }
   765  
   766  // TestOCSPFailClosedNoOCSPURL tests no OCSP URL
   767  func TestOCSPFailClosedNoOCSPURL(t *testing.T) {
   768  	cleanup()
   769  	defer cleanup()
   770  
   771  	setenv(cacheServerEnabledEnv, "false")
   772  	setenv(ocspTestNoOCSPURLEnv, "true")
   773  
   774  	config := &Config{
   775  		Account:      "fakeaccount11",
   776  		User:         "fakeuser",
   777  		Password:     "fakepassword",
   778  		LoginTimeout: 20 * time.Second,
   779  		OCSPFailOpen: OCSPFailOpenFalse,
   780  	}
   781  	var db *sql.DB
   782  	var err error
   783  	var testURL string
   784  	testURL, err = DSN(config)
   785  	if err != nil {
   786  		t.Fatalf("failed to build URL from Config: %v", config)
   787  	}
   788  
   789  	if db, err = sql.Open("snowflake", testURL); err != nil {
   790  		t.Fatalf("failed to open db. %v, err: %v", testURL, err)
   791  	}
   792  	defer db.Close()
   793  	if err = db.Ping(); err == nil {
   794  		t.Fatalf("should fail to ping. %v", testURL)
   795  	}
   796  	urlErr, ok := err.(*url.Error)
   797  	if !ok {
   798  		t.Fatalf("failed to extract error URL Error: %v", err)
   799  	}
   800  	driverErr, ok := urlErr.Err.(*SnowflakeError)
   801  	if !ok {
   802  		t.Fatalf("failed to extract error SnowflakeError: %v", err)
   803  	}
   804  	if driverErr.Number != ErrOCSPNoOCSPResponderURL {
   805  		t.Fatalf("should failed to connect %v", err)
   806  	}
   807  }