github.com/nginxinc/kubernetes-ingress@v1.12.5/internal/k8s/secrets/validation_test.go (about)

     1  package secrets
     2  
     3  import (
     4  	"testing"
     5  
     6  	v1 "k8s.io/api/core/v1"
     7  	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  )
     9  
    10  func TestValidateJWKSecret(t *testing.T) {
    11  	secret := &v1.Secret{
    12  		ObjectMeta: meta_v1.ObjectMeta{
    13  			Name:      "jwk-secret",
    14  			Namespace: "default",
    15  		},
    16  		Type: SecretTypeJWK,
    17  		Data: map[string][]byte{
    18  			"jwk": nil,
    19  		},
    20  	}
    21  
    22  	err := ValidateJWKSecret(secret)
    23  	if err != nil {
    24  		t.Errorf("ValidateJWKSecret() returned error %v", err)
    25  	}
    26  }
    27  
    28  func TestValidateJWKSecretFails(t *testing.T) {
    29  	tests := []struct {
    30  		secret *v1.Secret
    31  		msg    string
    32  	}{
    33  		{
    34  			secret: &v1.Secret{
    35  				ObjectMeta: meta_v1.ObjectMeta{
    36  					Name:      "jwk-secret",
    37  					Namespace: "default",
    38  				},
    39  				Type: "some-type",
    40  				Data: map[string][]byte{
    41  					"jwk": nil,
    42  				},
    43  			},
    44  			msg: "Incorrect type for JWK secret",
    45  		},
    46  		{
    47  			secret: &v1.Secret{
    48  				ObjectMeta: meta_v1.ObjectMeta{
    49  					Name:      "jwk-secret",
    50  					Namespace: "default",
    51  				},
    52  				Type: SecretTypeJWK,
    53  			},
    54  			msg: "Missing jwk for JWK secret",
    55  		},
    56  	}
    57  
    58  	for _, test := range tests {
    59  		err := ValidateJWKSecret(test.secret)
    60  		if err == nil {
    61  			t.Errorf("ValidateJWKSecret() returned no error for the case of %s", test.msg)
    62  		}
    63  	}
    64  }
    65  
    66  func TestValidateCASecret(t *testing.T) {
    67  	secret := &v1.Secret{
    68  		ObjectMeta: meta_v1.ObjectMeta{
    69  			Name:      "ingress-mtls-secret",
    70  			Namespace: "default",
    71  		},
    72  		Type: SecretTypeCA,
    73  		Data: map[string][]byte{
    74  			"ca.crt": validCert,
    75  		},
    76  	}
    77  
    78  	err := ValidateCASecret(secret)
    79  	if err != nil {
    80  		t.Errorf("ValidateCASecret() returned error %v", err)
    81  	}
    82  }
    83  
    84  func TestValidateCASecretFails(t *testing.T) {
    85  	tests := []struct {
    86  		secret *v1.Secret
    87  		msg    string
    88  	}{
    89  		{
    90  			secret: &v1.Secret{
    91  				ObjectMeta: meta_v1.ObjectMeta{
    92  					Name:      "ingress-mtls-secret",
    93  					Namespace: "default",
    94  				},
    95  				Type: "some-type",
    96  				Data: map[string][]byte{
    97  					"ca.crt": validCert,
    98  				},
    99  			},
   100  			msg: "Incorrect type for CA secret",
   101  		},
   102  		{
   103  			secret: &v1.Secret{
   104  				ObjectMeta: meta_v1.ObjectMeta{
   105  					Name:      "ingress-mtls-secret",
   106  					Namespace: "default",
   107  				},
   108  				Type: SecretTypeCA,
   109  			},
   110  			msg: "Missing ca.crt for CA secret",
   111  		},
   112  		{
   113  			secret: &v1.Secret{
   114  				ObjectMeta: meta_v1.ObjectMeta{
   115  					Name:      "ingress-mtls-secret",
   116  					Namespace: "default",
   117  				},
   118  				Type: SecretTypeCA,
   119  				Data: map[string][]byte{
   120  					"ca.crt": invalidCACertWithNoPEMBlock,
   121  				},
   122  			},
   123  			msg: "Invalid cert with no PEM block",
   124  		},
   125  		{
   126  			secret: &v1.Secret{
   127  				ObjectMeta: meta_v1.ObjectMeta{
   128  					Name:      "ingress-mtls-secret",
   129  					Namespace: "default",
   130  				},
   131  				Type: SecretTypeCA,
   132  				Data: map[string][]byte{
   133  					"ca.crt": invalidCACertWithWrongPEMBlock,
   134  				},
   135  			},
   136  			msg: "Invalid cert with wrong PEM block",
   137  		},
   138  		{
   139  			secret: &v1.Secret{
   140  				ObjectMeta: meta_v1.ObjectMeta{
   141  					Name:      "ingress-mtls-secret",
   142  					Namespace: "default",
   143  				},
   144  				Type: SecretTypeCA,
   145  				Data: map[string][]byte{
   146  					"ca.crt": invalidCACert,
   147  				},
   148  			},
   149  			msg: "Invalid cert",
   150  		},
   151  	}
   152  
   153  	for _, test := range tests {
   154  		err := ValidateCASecret(test.secret)
   155  		if err == nil {
   156  			t.Errorf("ValidateCASecret() returned no error for the case of %s", test.msg)
   157  		}
   158  	}
   159  }
   160  
   161  func TestValidateTLSSecret(t *testing.T) {
   162  	secret := &v1.Secret{
   163  		ObjectMeta: meta_v1.ObjectMeta{
   164  			Name:      "tls-secret",
   165  			Namespace: "default",
   166  		},
   167  		Type: v1.SecretTypeTLS,
   168  		Data: map[string][]byte{
   169  			"tls.crt": validCert,
   170  			"tls.key": validKey,
   171  		},
   172  	}
   173  
   174  	err := ValidateTLSSecret(secret)
   175  	if err != nil {
   176  		t.Errorf("ValidateTLSSecret() returned error %v", err)
   177  	}
   178  }
   179  
   180  func TestValidateTLSSecretFails(t *testing.T) {
   181  	tests := []struct {
   182  		secret *v1.Secret
   183  		msg    string
   184  	}{
   185  		{
   186  			secret: &v1.Secret{
   187  				ObjectMeta: meta_v1.ObjectMeta{
   188  					Name:      "tls-secret",
   189  					Namespace: "default",
   190  				},
   191  				Type: "some type",
   192  			},
   193  			msg: "Wrong type",
   194  		},
   195  		{
   196  			secret: &v1.Secret{
   197  				ObjectMeta: meta_v1.ObjectMeta{
   198  					Name:      "tls-secret",
   199  					Namespace: "default",
   200  				},
   201  				Type: v1.SecretTypeTLS,
   202  				Data: map[string][]byte{
   203  					"tls.crt": invalidCert,
   204  					"tls.key": validKey,
   205  				},
   206  			},
   207  			msg: "Invalid cert",
   208  		},
   209  		{
   210  			secret: &v1.Secret{
   211  				ObjectMeta: meta_v1.ObjectMeta{
   212  					Name:      "tls-secret",
   213  					Namespace: "default",
   214  				},
   215  				Type: v1.SecretTypeTLS,
   216  				Data: map[string][]byte{
   217  					"tls.crt": validCert,
   218  					"tls.key": invalidKey,
   219  				},
   220  			},
   221  			msg: "Invalid key",
   222  		},
   223  	}
   224  
   225  	for _, test := range tests {
   226  		err := ValidateTLSSecret(test.secret)
   227  		if err == nil {
   228  			t.Errorf("ValidateTLSSecret() returned no error for the case of %s", test.msg)
   229  		}
   230  	}
   231  }
   232  
   233  func TestValidateOIDCSecret(t *testing.T) {
   234  	secret := &v1.Secret{
   235  		ObjectMeta: meta_v1.ObjectMeta{
   236  			Name:      "oidc-secret",
   237  			Namespace: "default",
   238  		},
   239  		Type: SecretTypeOIDC,
   240  		Data: map[string][]byte{
   241  			"client-secret": nil,
   242  		},
   243  	}
   244  
   245  	err := ValidateOIDCSecret(secret)
   246  	if err != nil {
   247  		t.Errorf("ValidateOIDCSecret() returned error %v", err)
   248  	}
   249  }
   250  
   251  func TestValidateOIDCSecretFails(t *testing.T) {
   252  	tests := []struct {
   253  		secret *v1.Secret
   254  		msg    string
   255  	}{
   256  		{
   257  			secret: &v1.Secret{
   258  				ObjectMeta: meta_v1.ObjectMeta{
   259  					Name:      "oidc-secret",
   260  					Namespace: "default",
   261  				},
   262  				Type: "some-type",
   263  				Data: map[string][]byte{
   264  					"client-secret": nil,
   265  				},
   266  			},
   267  			msg: "Incorrect type for OIDC secret",
   268  		},
   269  		{
   270  			secret: &v1.Secret{
   271  				ObjectMeta: meta_v1.ObjectMeta{
   272  					Name:      "oidc-secret",
   273  					Namespace: "default",
   274  				},
   275  				Type: SecretTypeOIDC,
   276  			},
   277  			msg: "Missing client-secret for OIDC secret",
   278  		},
   279  		{
   280  			secret: &v1.Secret{
   281  				ObjectMeta: meta_v1.ObjectMeta{
   282  					Name:      "oidc-secret",
   283  					Namespace: "default",
   284  				},
   285  				Type: SecretTypeOIDC,
   286  				Data: map[string][]byte{
   287  					"client-secret": []byte("hello$$$"),
   288  				},
   289  			},
   290  			msg: "Invalid characters in OIDC client secret",
   291  		},
   292  		{
   293  			secret: &v1.Secret{
   294  				ObjectMeta: meta_v1.ObjectMeta{
   295  					Name:      "oidc-secret",
   296  					Namespace: "default",
   297  				},
   298  				Type: SecretTypeOIDC,
   299  				Data: map[string][]byte{
   300  					"client-secret": []byte("hello\t\n"),
   301  				},
   302  			},
   303  			msg: "Invalid newline in OIDC client secret",
   304  		},
   305  	}
   306  
   307  	for _, test := range tests {
   308  		err := ValidateOIDCSecret(test.secret)
   309  		if err == nil {
   310  			t.Errorf("ValidateOIDCSecret() returned no error for the case of %s", test.msg)
   311  		}
   312  	}
   313  }
   314  
   315  func TestValidateSecret(t *testing.T) {
   316  	tests := []struct {
   317  		secret *v1.Secret
   318  		msg    string
   319  	}{
   320  		{
   321  			secret: &v1.Secret{
   322  				ObjectMeta: meta_v1.ObjectMeta{
   323  					Name:      "tls-secret",
   324  					Namespace: "default",
   325  				},
   326  				Type: v1.SecretTypeTLS,
   327  				Data: map[string][]byte{
   328  					"tls.crt": validCert,
   329  					"tls.key": validKey,
   330  				},
   331  			},
   332  			msg: "Valid TLS secret",
   333  		},
   334  		{
   335  			secret: &v1.Secret{
   336  				ObjectMeta: meta_v1.ObjectMeta{
   337  					Name:      "ingress-mtls-secret",
   338  					Namespace: "default",
   339  				},
   340  				Type: SecretTypeCA,
   341  				Data: map[string][]byte{
   342  					"ca.crt": validCACert,
   343  				},
   344  			},
   345  			msg: "Valid CA secret",
   346  		},
   347  		{
   348  			secret: &v1.Secret{
   349  				ObjectMeta: meta_v1.ObjectMeta{
   350  					Name:      "jwk-secret",
   351  					Namespace: "default",
   352  				},
   353  				Type: SecretTypeJWK,
   354  				Data: map[string][]byte{
   355  					"jwk": nil,
   356  				},
   357  			},
   358  			msg: "Valid JWK secret",
   359  		},
   360  		{
   361  			secret: &v1.Secret{
   362  				ObjectMeta: meta_v1.ObjectMeta{
   363  					Name:      "oidc-secret",
   364  					Namespace: "default",
   365  				},
   366  				Type: SecretTypeOIDC,
   367  				Data: map[string][]byte{
   368  					"client-secret": nil,
   369  				},
   370  			},
   371  			msg: "Valid OIDC secret",
   372  		},
   373  	}
   374  
   375  	for _, test := range tests {
   376  		err := ValidateSecret(test.secret)
   377  		if err != nil {
   378  			t.Errorf("ValidateSecret() returned error %v for the case of %s", err, test.msg)
   379  		}
   380  	}
   381  }
   382  
   383  func TestValidateSecretFails(t *testing.T) {
   384  	tests := []struct {
   385  		secret *v1.Secret
   386  		msg    string
   387  	}{
   388  		{
   389  			secret: &v1.Secret{
   390  				ObjectMeta: meta_v1.ObjectMeta{
   391  					Name:      "tls-secret",
   392  					Namespace: "default",
   393  				},
   394  				Data: map[string][]byte{
   395  					"tls.crt": validCert,
   396  					"tls.key": validKey,
   397  				},
   398  			},
   399  			msg: "Missing type for TLS secret",
   400  		},
   401  		{
   402  			secret: &v1.Secret{
   403  				ObjectMeta: meta_v1.ObjectMeta{
   404  					Name:      "ingress-mtls-secret",
   405  					Namespace: "default",
   406  				},
   407  				Type: SecretTypeCA,
   408  			},
   409  			msg: "Missing ca.crt for CA secret",
   410  		},
   411  		{
   412  			secret: &v1.Secret{
   413  				ObjectMeta: meta_v1.ObjectMeta{
   414  					Name:      "jwk-secret",
   415  					Namespace: "default",
   416  				},
   417  				Type: SecretTypeJWK,
   418  			},
   419  			msg: "Missing jwk for JWK secret",
   420  		},
   421  	}
   422  
   423  	for _, test := range tests {
   424  		err := ValidateSecret(test.secret)
   425  		if err == nil {
   426  			t.Errorf("ValidateSecret() returned no error for the case of %s", test.msg)
   427  		}
   428  	}
   429  }
   430  
   431  func TestHasCorrectSecretType(t *testing.T) {
   432  	tests := []struct {
   433  		secretType v1.SecretType
   434  		expected   bool
   435  	}{
   436  		{
   437  			secretType: v1.SecretTypeTLS,
   438  			expected:   true,
   439  		},
   440  		{
   441  			secretType: SecretTypeCA,
   442  			expected:   true,
   443  		},
   444  		{
   445  			secretType: SecretTypeJWK,
   446  			expected:   true,
   447  		},
   448  		{
   449  			secretType: SecretTypeOIDC,
   450  			expected:   true,
   451  		},
   452  		{
   453  			secretType: "some-type",
   454  			expected:   false,
   455  		},
   456  	}
   457  
   458  	for _, test := range tests {
   459  		result := IsSupportedSecretType(test.secretType)
   460  		if result != test.expected {
   461  			t.Errorf("IsSupportedSecretType(%v) returned %v but expected %v", test.secretType, result, test.expected)
   462  		}
   463  	}
   464  }
   465  
   466  var (
   467  	validCert = []byte(`-----BEGIN CERTIFICATE-----
   468  MIIDLjCCAhYCCQDAOF9tLsaXWjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV
   469  UzELMAkGA1UECAwCQ0ExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
   470  ZDEbMBkGA1UEAwwSY2FmZS5leGFtcGxlLmNvbSAgMB4XDTE4MDkxMjE2MTUzNVoX
   471  DTIzMDkxMTE2MTUzNVowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMSEwHwYD
   472  VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGTAXBgNVBAMMEGNhZmUuZXhh
   473  bXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp6Kn7sy81
   474  p0juJ/cyk+vCAmlsfjtFM2muZNK0KtecqG2fjWQb55xQ1YFA2XOSwHAYvSdwI2jZ
   475  ruW8qXXCL2rb4CZCFxwpVECrcxdjm3teViRXVsYImmJHPPSyQgpiobs9x7DlLc6I
   476  BA0ZjUOyl0PqG9SJexMV73WIIa5rDVSF2r4kSkbAj4Dcj7LXeFlVXH2I5XwXCptC
   477  n67JCg42f+k8wgzcRVp8XZkZWZVjwq9RUKDXmFB2YyN1XEWdZ0ewRuKYUJlsm692
   478  skOrKQj0vkoPn41EE/+TaVEpqLTRoUY3rzg7DkdzfdBizFO2dsPNFx2CW0jXkNLv
   479  Ko25CZrOhXAHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKHFCcyOjZvoHswUBMdL
   480  RdHIb383pWFynZq/LuUovsVA58B0Cg7BEfy5vWVVrq5RIkv4lZ81N29x21d1JH6r
   481  jSnQx+DXCO/TJEV5lSCUpIGzEUYaUPgRyjsM/NUdCJ8uHVhZJ+S6FA+CnOD9rn2i
   482  ZBePCI5rHwEXwnnl8ywij3vvQ5zHIuyBglWr/Qyui9fjPpwWUvUm4nv5SMG9zCV7
   483  PpuwvuatqjO1208BjfE/cZHIg8Hw9mvW9x9C+IQMIMDE7b/g6OcK7LGTLwlFxvA8
   484  7WjEequnayIphMhKRXVf1N349eN98Ez38fOTHTPbdJjFA/PcC+Gyme+iGt5OQdFh
   485  yRE=
   486  -----END CERTIFICATE-----`)
   487  
   488  	validKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
   489  MIIEowIBAAKCAQEAqeip+7MvNadI7if3MpPrwgJpbH47RTNprmTStCrXnKhtn41k
   490  G+ecUNWBQNlzksBwGL0ncCNo2a7lvKl1wi9q2+AmQhccKVRAq3MXY5t7XlYkV1bG
   491  CJpiRzz0skIKYqG7Pcew5S3OiAQNGY1DspdD6hvUiXsTFe91iCGuaw1Uhdq+JEpG
   492  wI+A3I+y13hZVVx9iOV8FwqbQp+uyQoONn/pPMIM3EVafF2ZGVmVY8KvUVCg15hQ
   493  dmMjdVxFnWdHsEbimFCZbJuvdrJDqykI9L5KD5+NRBP/k2lRKai00aFGN684Ow5H
   494  c33QYsxTtnbDzRcdgltI15DS7yqNuQmazoVwBwIDAQABAoIBAQCPSdSYnQtSPyql
   495  FfVFpTOsoOYRhf8sI+ibFxIOuRauWehhJxdm5RORpAzmCLyL5VhjtJme223gLrw2
   496  N99EjUKb/VOmZuDsBc6oCF6QNR58dz8cnORTewcotsJR1pn1hhlnR5HqJJBJask1
   497  ZEnUQfcXZrL94lo9JH3E+Uqjo1FFs8xxE8woPBqjZsV7pRUZgC3LhxnwLSExyFo4
   498  cxb9SOG5OmAJozStFoQ2GJOes8rJ5qfdvytgg9xbLaQL/x0kpQ62BoFMBDdqOePW
   499  KfP5zZ6/07/vpj48yA1Q32PzobubsBLd3Kcn32jfm1E7prtWl+JeOFiOznBQFJbN
   500  4qPVRz5hAoGBANtWyxhNCSLu4P+XgKyckljJ6F5668fNj5CzgFRqJ09zn0TlsNro
   501  FTLZcxDqnR3HPYM42JERh2J/qDFZynRQo3cg3oeivUdBVGY8+FI1W0qdub/L9+yu
   502  edOZTQ5XmGGp6r6jexymcJim/OsB3ZnYOpOrlD7SPmBvzNLk4MF6gxbXAoGBAMZO
   503  0p6HbBmcP0tjFXfcKE77ImLm0sAG4uHoUx0ePj/2qrnTnOBBNE4MvgDuTJzy+caU
   504  k8RqmdHCbHzTe6fzYq/9it8sZ77KVN1qkbIcuc+RTxA9nNh1TjsRne74Z0j1FCLk
   505  hHcqH0ri7PYSKHTE8FvFCxZYdbuB84CmZihvxbpRAoGAIbjqaMYPTYuklCda5S79
   506  YSFJ1JzZe1Kja//tDw1zFcgVCKa31jAwciz0f/lSRq3HS1GGGmezhPVTiqLfeZqc
   507  R0iKbhgbOcVVkJJ3K0yAyKwPTumxKHZ6zImZS0c0am+RY9YGq5T7YrzpzcfvpiOU
   508  ffe3RyFT7cfCmfoOhDCtzukCgYB30oLC1RLFOrqn43vCS51zc5zoY44uBzspwwYN
   509  TwvP/ExWMf3VJrDjBCH+T/6sysePbJEImlzM+IwytFpANfiIXEt/48Xf60Nx8gWM
   510  uHyxZZx/NKtDw0V8vX1POnq2A5eiKa+8jRARYKJLYNdfDuwolxvG6bZhkPi/4EtT
   511  3Y18sQKBgHtKbk+7lNJVeswXE5cUG6EDUsDe/2Ua7fXp7FcjqBEoap1LSw+6TXp0
   512  ZgrmKE8ARzM47+EJHUviiq/nupE15g0kJW3syhpU9zZLO7ltB0KIkO9ZRcmUjo8Q
   513  cpLlHMAqbLJ8WYGJCkhiWxyal6hYTyWY4cVkC0xtTl/hUE9IeNKo
   514  -----END RSA PRIVATE KEY-----`)
   515  
   516  	invalidCert = []byte(`-----BEGIN CERTIFICATE-----
   517  -----END CERTIFICATE-----`)
   518  
   519  	invalidKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
   520  -----END RSA PRIVATE KEY-----`)
   521  
   522  	validCACert = validCert
   523  
   524  	invalidCACertWithNoPEMBlock []byte
   525  
   526  	invalidCACertWithWrongPEMBlock = []byte(`-----BEGIN PRIVATE KEY-----
   527  -----END PRIVATE KEY-----`)
   528  
   529  	invalidCACert = []byte(`-----BEGIN CERTIFICATE-----
   530  -----END CERTIFICATE-----`)
   531  )