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 )