Test x509 intermediates correctly
This commit is contained in:
		
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-expired.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-expired.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIBpTCCAUugAwIBAgIUPV4LAC5KK8YWY1FegyTuhkGUr3EwCgYIKoZIzj0EAwIw | ||||
| GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMB4XDTkwMTIzMTIzNTkwMFoXDTkw | ||||
| MTIzMTIzNTkwMFowFDESMBAGA1UEAxMJTXkgQ2xpZW50MFkwEwYHKoZIzj0CAQYI | ||||
| KoZIzj0DAQcDQgAEyYUnseNUN87rfHgekrfZu5sj4wlt5LYr3JYZZkfSbsb+BW3/ | ||||
| RzX02ifjp+8w7mI4qUGg6y6J7oXHGFT3uj9kj6N1MHMwDgYDVR0PAQH/BAQDAgWg | ||||
| MBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKsX | ||||
| EnXwDg8j2LIEM1QzmFrE6537MB8GA1UdIwQYMBaAFF+p0JcY31pz+mjNZnjv0Gum | ||||
| 92vZMAoGCCqGSM49BAMCA0gAMEUCIG4FBcb57oqOCoaFiJ+Yx6S0zkaash7bTv3V | ||||
| CIy9JvFdAiEAy8bf2S9EkvZyURZ6ycgEMnekll57Ebze6rjlPx8+B1Y= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-valid.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-valid.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIBqDCCAU2gAwIBAgIUfbqeieihh/oERbfvRm38XvS/xHAwCgYIKoZIzj0EAwIw | ||||
| GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMCAXDTE2MTAxMTA1MDYwMFoYDzIx | ||||
| MTYwOTE3MDUwNjAwWjAUMRIwEAYDVQQDEwlNeSBDbGllbnQwWTATBgcqhkjOPQIB | ||||
| BggqhkjOPQMBBwNCAARv6N4R/sjMR65iMFGNLN1GC/vd7WhDW6J4X/iAjkRLLnNb | ||||
| KbRG/AtOUZ+7upJ3BWIRKYbOabbQGQe2BbKFiap4o3UwczAOBgNVHQ8BAf8EBAMC | ||||
| BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU | ||||
| K/pZOWpNcYai6eHFpmJEeFpeQlEwHwYDVR0jBBgwFoAUX6nQlxjfWnP6aM1meO/Q | ||||
| a6b3a9kwCgYIKoZIzj0EAwIDSQAwRgIhAIWTKw/sjJITqeuNzJDAKU4xo1zL+xJ5 | ||||
| MnVCuBwfwDXCAiEAw/1TA+CjPq9JC5ek1ifR0FybTURjeQqYkKpve1dveps= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| { | ||||
|     "signing": { | ||||
|         "profiles": { | ||||
|             "valid": { | ||||
|                 "expiry": "876000h", | ||||
|                 "usages": [ | ||||
|                     "signing", | ||||
|                     "key encipherment", | ||||
|                     "client auth" | ||||
|                 ] | ||||
|             }, | ||||
|             "expired": { | ||||
|                 "expiry": "1h", | ||||
|                 "not_before": "1990-12-31T23:59:00Z", | ||||
|                 "not_after": "1990-12-31T23:59:00Z", | ||||
|                 "usages": [ | ||||
|                     "signing", | ||||
|                     "key encipherment", | ||||
|                     "client auth" | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										3
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "CN": "My Client" | ||||
| } | ||||
							
								
								
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/generate.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/generate.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| # Copyright 2016 The Kubernetes Authors. | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
|  | ||||
| cfssl gencert -initca root.csr.json | cfssljson -bare root | ||||
|  | ||||
| cfssl gencert -initca intermediate.csr.json | cfssljson -bare intermediate | ||||
| cfssl sign -ca root.pem -ca-key root-key.pem -config intermediate.config.json intermediate.csr | cfssljson -bare intermediate | ||||
|  | ||||
| cfssl gencert -ca intermediate.pem -ca-key intermediate-key.pem -config client.config.json --profile=valid   client.csr.json | cfssljson -bare client-valid | ||||
| cfssl gencert -ca intermediate.pem -ca-key intermediate-key.pem -config client.config.json --profile=expired client.csr.json | cfssljson -bare client-expired | ||||
|   | ||||
							
								
								
									
										18
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| { | ||||
|     "signing": { | ||||
|         "default": { | ||||
|             "usages": [ | ||||
|                 "digital signature", | ||||
|                 "cert sign", | ||||
|                 "crl sign", | ||||
|                 "signing", | ||||
|                 "key encipherment", | ||||
|                 "client auth" | ||||
|             ], | ||||
|             "expiry": "876000h", | ||||
|             "ca_constraint": { | ||||
|                 "is_ca": true | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|     "CN": "Intermediate-CA", | ||||
|     "ca": { | ||||
|         "expiry": "876000h" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIBqDCCAU6gAwIBAgIUfqZtjoFgczZ+oQZbEC/BDSS2J6wwCgYIKoZIzj0EAwIw | ||||
| EjEQMA4GA1UEAxMHUm9vdC1DQTAgFw0xNjEwMTEwNTA2MDBaGA8yMTE2MDkxNzA1 | ||||
| MDYwMFowGjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMFkwEwYHKoZIzj0CAQYI | ||||
| KoZIzj0DAQcDQgAEyWHEMMCctJg8Xa5YWLqaCPbk3MjB+uvXac42JM9pj4k9jedD | ||||
| kpUJRkWIPzgJI8Zk/3cSzluUTixP6JBSDKtwwaN4MHYwDgYDVR0PAQH/BAQDAgGm | ||||
| MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE | ||||
| FF+p0JcY31pz+mjNZnjv0Gum92vZMB8GA1UdIwQYMBaAFB7P6+i4/pfNjqZgJv/b | ||||
| dgA7Fe4tMAoGCCqGSM49BAMCA0gAMEUCIQCTT1YWQZaAqfQ2oBxzOkJE2BqLFxhz | ||||
| 3smQlrZ5gCHddwIgcvT7puhYOzAgcvMn9+SZ1JOyZ7edODjshCVCRnuHK2c= | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| { | ||||
|     "CN": "Root-CA", | ||||
|     "ca": { | ||||
|         "expiry": "876000h" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIBizCCATGgAwIBAgIUH4plk9qwD61FVXgiOTngFU5FeSkwCgYIKoZIzj0EAwIw | ||||
| EjEQMA4GA1UEAxMHUm9vdC1DQTAgFw0xNjEwMTEwNTA2MDBaGA8yMTE2MDkxNzA1 | ||||
| MDYwMFowEjEQMA4GA1UEAxMHUm9vdC1DQTBZMBMGByqGSM49AgEGCCqGSM49AwEH | ||||
| A0IABI2CsrAnMGT8P2VGU2MLo5pv86Z74kcV9hgkLJUkSaeNyc1s89w7X5V2wvwu | ||||
| iWEJRGm5RoZJausmyZLZEoKEVXejYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB | ||||
| Af8EBTADAQH/MB0GA1UdDgQWBBQez+vouP6XzY6mYCb/23YAOxXuLTAfBgNVHSME | ||||
| GDAWgBQez+vouP6XzY6mYCb/23YAOxXuLTAKBggqhkjOPQQDAgNIADBFAiBGclts | ||||
| vJRM+QMVoV/1L9b+hvhgLIp/OupUFsSOReefIwIhALY06hBklyh8eFwuBtyX2VcE | ||||
| 8xlVn4/5idUvc3Xv2h9s | ||||
| -----END CERTIFICATE----- | ||||
| @@ -52,28 +52,34 @@ func New(opts x509.VerifyOptions, user UserConversion) *Authenticator { | ||||
|  | ||||
| // AuthenticateRequest authenticates the request using presented client certificates | ||||
| func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool, error) { | ||||
| 	if req.TLS == nil { | ||||
| 	if req.TLS == nil || len(req.TLS.PeerCertificates) == 0 { | ||||
| 		return nil, false, nil | ||||
| 	} | ||||
|  | ||||
| 	// Use intermediates, if provided | ||||
| 	optsCopy := a.opts | ||||
| 	if optsCopy.Intermediates == nil && len(req.TLS.PeerCertificates) > 1 { | ||||
| 		optsCopy.Intermediates = x509.NewCertPool() | ||||
| 		for _, intermediate := range req.TLS.PeerCertificates[1:] { | ||||
| 			optsCopy.Intermediates.AddCert(intermediate) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	chains, err := req.TLS.PeerCertificates[0].Verify(optsCopy) | ||||
| 	if err != nil { | ||||
| 		return nil, false, err | ||||
| 	} | ||||
|  | ||||
| 	var errlist []error | ||||
| 	for _, cert := range req.TLS.PeerCertificates { | ||||
| 		chains, err := cert.Verify(a.opts) | ||||
| 	for _, chain := range chains { | ||||
| 		user, ok, err := a.user.User(chain) | ||||
| 		if err != nil { | ||||
| 			errlist = append(errlist, err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		for _, chain := range chains { | ||||
| 			user, ok, err := a.user.User(chain) | ||||
| 			if err != nil { | ||||
| 				errlist = append(errlist, err) | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			if ok { | ||||
| 				return user, ok, err | ||||
| 			} | ||||
| 		if ok { | ||||
| 			return user, ok, err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil, false, utilerrors.NewAggregate(errlist) | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import ( | ||||
| 	"crypto/x509" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| @@ -507,6 +508,10 @@ PKJQCs0CM0zkesktuLi/gFpuB0nEwyOgLg== | ||||
| ) | ||||
|  | ||||
| func TestX509(t *testing.T) { | ||||
| 	multilevelOpts := DefaultVerifyOptions() | ||||
| 	multilevelOpts.Roots = x509.NewCertPool() | ||||
| 	multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0]) | ||||
|  | ||||
| 	testCases := map[string]struct { | ||||
| 		Insecure bool | ||||
| 		Certs    []*x509.Certificate | ||||
| @@ -659,6 +664,24 @@ func TestX509(t *testing.T) { | ||||
| 			ExpectOK:  false, | ||||
| 			ExpectErr: true, | ||||
| 		}, | ||||
|  | ||||
| 		"multi-level, valid": { | ||||
| 			Opts:  multilevelOpts, | ||||
| 			Certs: getCertsFromFile(t, "client-valid", "intermediate"), | ||||
| 			User:  CommonNameUserConversion, | ||||
|  | ||||
| 			ExpectUserName: "My Client", | ||||
| 			ExpectOK:       true, | ||||
| 			ExpectErr:      false, | ||||
| 		}, | ||||
| 		"multi-level, expired": { | ||||
| 			Opts:  multilevelOpts, | ||||
| 			Certs: getCertsFromFile(t, "client-expired", "intermediate"), | ||||
| 			User:  CommonNameUserConversion, | ||||
|  | ||||
| 			ExpectOK:  false, | ||||
| 			ExpectErr: true, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for k, testCase := range testCases { | ||||
| @@ -718,6 +741,19 @@ func getRootCertPoolFor(t *testing.T, certs ...string) *x509.CertPool { | ||||
| 	return pool | ||||
| } | ||||
|  | ||||
| func getCertsFromFile(t *testing.T, names ...string) []*x509.Certificate { | ||||
| 	certs := []*x509.Certificate{} | ||||
| 	for _, name := range names { | ||||
| 		filename := "testdata/" + name + ".pem" | ||||
| 		data, err := ioutil.ReadFile(filename) | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("error reading %s: %v", filename, err) | ||||
| 		} | ||||
| 		certs = append(certs, getCert(t, string(data))) | ||||
| 	} | ||||
| 	return certs | ||||
| } | ||||
|  | ||||
| func getCert(t *testing.T, pemData string) *x509.Certificate { | ||||
| 	pemBlock, _ := pem.Decode([]byte(pemData)) | ||||
| 	cert, err := x509.ParseCertificate(pemBlock.Bytes) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jordan Liggitt
					Jordan Liggitt