diff --git a/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_1.pem b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_1.pem new file mode 100644 index 000000000..c56852dca --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_1.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIAvxtZy9aI/lEt6LVLIhVrWLSwmlMFThU/nZUPr88nA5yKzJMyKbW/ +QA+umam9YtO78WwzriTGC9qwW6+t+liXrcCgBwYFK4EEACOhgYkDgYYABAGzIO9n +tdTx6oVg1O59ljYP4FHY9RNUy+wHeXFnB6fo9asGg9jwLMg/iX0F+whFkllQjNLf +kKp/9ATWQHrzSbzuqwB9UU5zfQ3ulhMwEBpxbM6aSi1HyYtc5pQn7KB6h1VXiuQK +CIj4kVYHClZuKz0om/XAJL4vWVDwJqDBN6m9Yi9ZLQ== +-----END EC PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_2.pem b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_2.pem new file mode 100644 index 000000000..611a4ba3b --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_2.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBtxiwrrDmi1U+NxClUKIr2cvmL6PPLxjAULjPuORt0AWbqKakphSJ +43VmIbPBBCuLnN2PuVS9N8jLDlR1KUnnFSGgBwYFK4EEACOhgYkDgYYABAEgshGY +Oflwnz2SQOWIkvSPmijMhS4nWmLYedR2H/Dg9c9nuiyQqL3XpqkPnQQwqOgcXjMT +hTec2tiLcRS3Gj02yQEpe/6Do6if4K4cQ9KsNtVHsn0bibsqLtRuvI7xUu9JJAs7 +vSLNUtmxVzFo4s4spnIjLT71uz1Vag/NrKwot7cz4g== +-----END EC PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_3.pem b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_3.pem new file mode 100644 index 000000000..1bd6e0a34 --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/ecdsa_3.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIAQTHP4V93rz1w1D+jF1Jvx5QHzkQQIYxbN1LPuvQjEoplQrjZ4Qiu +h9mKK6DBCaDlfSos+wnTOlZH1z1tpa9soPOgBwYFK4EEACOhgYkDgYYABAFn+QOY +a937Lp+WO1S+zJU9ITnzdvjqQtD/TjtJPQsllV8rD0QNXZb/pLFQFZtDEehiZKEu +WA0REGNs+rVMO63YZAAyDMwZTz87ulH23OR6EaoyDp9qEPx7kpxgaJqeIztla2t8 +SLVpv/FPR92E/OmguT6sFI5mP0AhV8UVlLYuHaovnw== +-----END EC PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testdata/rsa_1.pem b/plugin/pkg/authenticator/token/oidc/testdata/rsa_1.pem new file mode 100644 index 000000000..2c4a9238c --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/rsa_1.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0pXWMYjWRjBEds/fKj/u9r2E6SIDx0J+TAg+eyVeR20Ky9jZ +mIXW5zSxE/EKpNQpiBWm1e6G9kmhMuqjr7g455S7E+3rD3OVkdTT6SU5AKBNSFoR +XUd+G/YJEtRzrpEYNtEJHkxUxWuyfCHblHSt+wsrE6t0DccCqC87lKQiGb/QfC8u +P6ZS99SCjKBEFp1fZvyNkYwStFc2OH5fBGPXXb6SNsquvDeKX9NeWjXkmxDkbOg2 +kSkel4s/zw5KwcW3JzERfEcLStrDQ8fRbJ1C3uC088sUk4q4APQmKI/8FTvJe431 +Vne9sOSptphiqCjlR+Knja58rc/vt4TkSPZf2wIDAQABAoIBAQDO3UgjMtOi8Wlf ++YW1IEbjdXrp9XMWu9gLYpHWMPgzXAeeBfCDJv7b8uP8ve2By7TcrMBOKVnE+MF0 +nhCb3nFv9KftxOsDK70DG7nrrpgXaGFisK+cHU3hs8hoCfF1y6yotKGrdLpVkR0t +Wak1ZYU/NlJjqSqBGj0e7/8sXivtc7oME8tBBRBCEa8OqPqaelCInfFF1rX5vmxX +pQjPpZoA+vroSJy8SYE0N5oqtGwOPT+9rVuDOL10eaMbGUcssZl8ofwuvzOYPMW4 +KFSVtvdtKnACq94Qy6XQbK5hZbZXSpzxANKq8SFyG2N1wOlpu/ktdXqkyDs08AZY +c/KkpXspAoGBAPdC73GOZn/hxzkwZ2Dl+S9rgrLT3VbeuhMp6GXSdiT+f9babMuw +HlYw6uULmvL1gD/0GmyWrHopPFJxodBG5SlwYS5wl49slcxeKCjK26vbNfK2eCbu +9uMtED4dN/5NlaXF4hqy/FmSyaFhQT+5hvx8n/zvLsgpuSQ+SCiDAHMfAoGBANoH +FCZeCWzzUFhObYG9wxGJ9FBPQa0htafIYEgTwezlKPsrfXfCTnVg1lLkr6Z4IwYQ +9VufJZNAc5V0X9H/ceyKJYxhQ+E01NEVzVpoK8fOC4yCYSYtbJnqkOUQzZJzkjFT +mNcIa8o4UrBOWzMhMQa0AOZH4VrbtZDCZhid+hfFAoGAAbKh9kOmDIa+WXQtoYqy +tVKlqRivUmNhH7SP9fMGAKcGtbD2QkfJTYo0crIrtDNfWBETBV/be1NBKMfC9q0l +8azl3e3D/KYgOTEEUZNjAsEUk8AQ/yNw6opqrCKDOenKd0LulIRaGztYyxTh39Ak +TyOD7bauuY0fylHrKOwNWr0CgYEAsVZ0o0h1rjKyNUGFfLQWyFtHZ1Mv/lye3tvy +xG2dnMxAaxvSr+hR3NNpQH9WB7dL9ZExoNZvv7f6y6OelLaLuXQcWnR6u+E3AOIU +5+Y3RgtoBV+/GUh1PzQ1qrviGa77SDfQ54an9hGd4F27fHkQ4XzkBmqM+FQg+J/G +X1uPomkCgYBo4ZBEA20Wvf1k2iWOVdfsxZNeOLxwcN5x89dAvm0v6RHg2NMy+XKw +Rj+YRuudFdxfg39J/V/Md9qsvjW+4FthD8GhgPs22dksV+7j6ApWkYTmIKG4rmh3 +RhHOr6uLg9BeShnlvMMaMJKf2eA7SaVtmuS6uBGgEUNaa3qEBq0R+Q== +-----END RSA PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testdata/rsa_2.pem b/plugin/pkg/authenticator/token/oidc/testdata/rsa_2.pem new file mode 100644 index 000000000..e89fdb868 --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/rsa_2.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxmLv1fqjacxZu5jyfQzytwjdt9/BBDzPM6G+R92YvsB7o2FH +ISiySbT8pyj7wGUgDvBdc9+GT3thf2pKGl/THaYJCLbh90GXVMTTak8Najqp2Qod +kxIpjSOBgukmd0LUtUVGKJg7YTEqsxAUmn9mfFiUZ6ixHr0U2NAXu7TF4dw7C9bt +ORi9DKDfUhEiV3Vcyrc5d/9VdmWG6fs/kq0B/6AboiSIIGAKSugNi4BgV7rNZYwZ +37UT72CW28TQQuuAtmTgXWMkfeWZiQKD1P8Nl1byORpgivp2A+2pMNlcLuogVhGY +TIZstbeMqoPyLW57GitWDg1tbakwJdCR23gCKQIDAQABAoIBACZmDf//1FNtD01F +TGIx+GS/HZMyhvyX/I8E1ny4gpEhVo0IDil35BJqKqD8SMYzjKH3mk8MS8Xknrl3 +zEIQnB9X/NWn+FLQakcpFba0+GbAVhHBaHoIAOzlm3LIR/67e8peTzcaSBwG1Tn1 +eddxo1ecGZV6zFWjyX4xwPY/BjIyA/b1LewqIK6W/I4u3RwtEzqANV9ddVbFH53e +Y+i2X1HVuLm0LETsX4jB/G/ZDP6Y101gOwPFddm+h1ixZ2jrAkyTbvYL5ukIsU8Z +okIEZsd6nv08YN+LOXOPh0CxvgHI347RDzgfbDmHGqq8gh20+wLP/MV+dOiBBAJT +RfnoFcUCgYEA8SpMW64CNhRkH3Nv5A5ffSOa7NqiN7OdNEswgcgkAbjR5YsTATPg +p9iWqGcEodX1FWjnL2NLMdMvYxh4MwMCACIa8FQ2/RDEwViaVjxcOK64MIvyvnNq +NObx8pMClUBXWF/llxxTR+/CJWRdCABBm56lQPuuX/qEi/xqybHPcAcCgYEA0pb9 +FGmGhDXl3bG3zNNIim+FuqG0xQoIjVPwdvkMI30h/ii6qs3jxwHlw6KBf8AI9wI+ +bWbzhwcYVkS6It0Yj4q/mqOVHi89frrAQygsJkMQkdl8WiWwPeiiIdsHYTUcBv5+ +i6YLs8ycnzMeFAxg8kuxrq6mm3yW6u5CuInsEE8CgYAWXqUMj/x2hbevzyZe0hJ7 +ahURyUnovsljM2JBd44XdsxJbXgK0YQSLZ3z6vJcDJuaK8vd8mjkK0GnAHsNyEak +OoWjKzyahrapdI2EWD75pwNAxYpzrgL4+z8QECDaNUik0uhZ9u+mqY+ppkCW4Gc1 +hyau+2l2T6eB0J0bLloeewKBgQC+fZn8JuBpI6AEg8ew3cYWg37CLZgpTEQkIzO3 +StyyFXT0RL9l1cwerha6ensNphX16e+yYpgTIlXfY1fERZ776RQcu7Adl7nWsvNL +TEFzcuLAK60SlljwB0jxuwDX64SoxviNNewL/iAG2eRxWikvw0y8qHtI1tBlPpTX +/NqufQKBgD1jAPRgu+IN9IDXoqnMiXbSfrVsJ1ndyPCRBq4dfvawcbEDTZfkiid0 +aNrdRoOETfLCynAcG6o6uS3+2sumzXLrMNr8MDF8NEa2Rh8nN3IjZqESV4CNgaV6 +JhAlWFp+AvYv6N1iHK52nNAFiX/cfaMpWTUKqk2Z4VZCr5qhLUVs +-----END RSA PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testdata/rsa_3.pem b/plugin/pkg/authenticator/token/oidc/testdata/rsa_3.pem new file mode 100644 index 000000000..3c660ed19 --- /dev/null +++ b/plugin/pkg/authenticator/token/oidc/testdata/rsa_3.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA1uO3LV0wHadHjQb8U8KGUpzlZTyBHlinL7lF5yKk2hXOyssT +Z0UVF6ofPq/L+ZN5VkTb1FJWMEBiX1BgXlboDdYKAYTl1QaeEQrfrAM4gp2FdWS4 +fMUuagFdVXs8T2J4GGPEE83ybwz/YEM3p83Qojifvx/IjVtuHCMkUpcj92scjsCY +EeSKRjJicVBmJ1RK0ShEorHhnYmokKYsPl41mV5VdmWZOtmPK4jV05cBfg7eC7yI +cwwYhowLkYvd9d9H74otK5tD7KTxFG6JJ0N5zwf6XBRcXBWKstfOOZ5Qgo9z0Tkm +n3Klp9vwun25aaA1MlSSByByiCb7qvS8jhqMkQIDAQABAoIBAQCjN58AU9GiFFai +ZXXuYMgJo6YRON2RoSCLfRv9LTEtfHbvTUPVooEc0lidEoXJcRwuTGr0X/2a9KxD +XRd1UGk9aR98e+bd4QLaSvoM+v1HKEIgInqGOnbAiXzM2qe6XD5/t/dMW5cShjrK +cQOq7wbS0FN1pbx8sb92m7KREL9+wnXuOCHYtublRf7arsMkaZcpSBBaI+raMaZR +dUC+LmalIvR8+dNegducwWsdE8/Vh+xq97ZbNFlyut3JOvfuHmaAOvUsX/4touj2 +dDkJmvzvmpTBG888t+6hv9eKWaacsTAKuPLThRBD53coTEvHK8iic9fOok65y5Bn +nFP/irUpAoGBAPUsPoAPwcNajZX/E4XeG/2eV+IHMxYR9gJwBzpoUfwHr5mR54HK +POia/z7/M2KVV9kMWBlbTumIHSEylEEDCCKNNIe1gHBxQ7uGuaf+vVXpVgjBigUz +7oiCjb5RdjevfiyudX/z0B9IQSI9djCXebifEHKpUxAOmU3oP0SEMULLAoGBAOBh +G+fDouMU7QN93NG0hssu44yc7xQhb7VLB+isrEQASVG2xWkd3iDrdRxwHAHZqxFd +4DRzDTFC7yeR+FEbVVkWQRaeDwFJM1zmRTXsYjBkK49GNzB4QEtHvPouuxMAQ4UD +zJ9a3LEDSs867R7XEbNF8j9NC9z0vk7w9bHTA1aTAoGBAODUUQBY8sQ1zy8lOf8B +/sMmKMti9Mshb2su1sIOFli7p6F5tkZEcnSQZs+bccDO2T92XXfrTsNDigr+egvg +Pt6IhQqKPB1hEM7wLmLLbU9Sag4fhXVd+TmAF4HW7EUGjvtkhOXwbQOy2+ANYswO +rJXMcGXltwE7kgRqnVI0s4PfAoGBALUrM5Dq0bZwyv6qvYVFMiEUdv6uKAwlA0Fq +l7Qy19UANjMYVEUPrK7/7stLahHEYu/e0I0I6HoCBX/5yHoUi9Emut88N/ld1W8J +LpDfkFhqSRGiLCWisqcWAWwwFzS8XcgkzS9N+iui8OBqP9NK7CvIKlUaLJ33r0Gm +JXuzWVqpAoGBAIQ8+YuvFfyhwXuWwQbzxVpWRURH0FRu8KfFIkFFbdyht6leYXuj +uxcrcHWzkEPSLO22BoJX8ECHq4LadAIjkkpr5GCikKCF+r/bq50RnECqvfoJ629J +gA87C8cLU3dXmSYd+vSg6icZyncTmXyyEV0dqoUGJ2M33kE6hYAbc/ic +-----END RSA PRIVATE KEY----- diff --git a/plugin/pkg/authenticator/token/oidc/testing/provider.go b/plugin/pkg/authenticator/token/oidc/testing/provider.go deleted file mode 100644 index ae7353ff2..000000000 --- a/plugin/pkg/authenticator/token/oidc/testing/provider.go +++ /dev/null @@ -1,200 +0,0 @@ -/* -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. -*/ - -package testing - -import ( - "bytes" - "crypto/rand" - "crypto/rsa" - "crypto/tls" - "crypto/x509" - "crypto/x509/pkix" - "encoding/json" - "encoding/pem" - "fmt" - "io/ioutil" - "math/big" - "net" - "net/http" - "net/http/httptest" - "net/url" - "os" - "path" - "path/filepath" - "testing" - "time" - - "github.com/coreos/go-oidc/jose" - "github.com/coreos/go-oidc/key" - "github.com/coreos/go-oidc/oidc" -) - -// NewOIDCProvider provides a bare minimum OIDC IdP Server useful for testing. -func NewOIDCProvider(t *testing.T, issuerPath string) *OIDCProvider { - privKey, err := key.GeneratePrivateKey() - if err != nil { - t.Fatalf("Cannot create OIDC Provider: %v", err) - return nil - } - - op := &OIDCProvider{ - Mux: http.NewServeMux(), - PrivKey: privKey, - issuerPath: issuerPath, - } - - op.Mux.HandleFunc(path.Join(issuerPath, "/.well-known/openid-configuration"), op.handleConfig) - op.Mux.HandleFunc(path.Join(issuerPath, "/keys"), op.handleKeys) - - return op -} - -type OIDCProvider struct { - Mux *http.ServeMux - PCFG oidc.ProviderConfig - PrivKey *key.PrivateKey - issuerPath string -} - -func (op *OIDCProvider) ServeTLSWithKeyPair(cert, key string) (*httptest.Server, error) { - srv := httptest.NewUnstartedServer(op.Mux) - - srv.TLS = &tls.Config{Certificates: make([]tls.Certificate, 1)} - var err error - srv.TLS.Certificates[0], err = tls.LoadX509KeyPair(cert, key) - if err != nil { - return nil, fmt.Errorf("Cannot load cert/key pair: %v", err) - } - srv.StartTLS() - - // The issuer's URL is extended by an optional path. This ensures that the plugin can - // handle issuers that use a non-root path for discovery (see kubernetes/kubernetes#29749). - srv.URL = srv.URL + op.issuerPath - - u, err := url.Parse(srv.URL) - if err != nil { - return nil, err - } - pathFor := func(p string) *url.URL { - u2 := *u // Shallow copy. - u2.Path = path.Join(u2.Path, p) - return &u2 - } - - op.PCFG = oidc.ProviderConfig{ - Issuer: u, - AuthEndpoint: pathFor("/auth"), - TokenEndpoint: pathFor("/token"), - KeysEndpoint: pathFor("/keys"), - ResponseTypesSupported: []string{"code"}, - SubjectTypesSupported: []string{"public"}, - IDTokenSigningAlgValues: []string{"RS256"}, - } - return srv, nil -} - -func (op *OIDCProvider) handleConfig(w http.ResponseWriter, req *http.Request) { - b, err := json.Marshal(&op.PCFG) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "application/json") - w.Write(b) -} - -func (op *OIDCProvider) handleKeys(w http.ResponseWriter, req *http.Request) { - keys := struct { - Keys []jose.JWK `json:"keys"` - }{ - Keys: []jose.JWK{op.PrivKey.JWK()}, - } - - b, err := json.Marshal(keys) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(time.Hour.Seconds()))) - w.Header().Set("Expires", time.Now().Add(time.Hour).Format(time.RFC1123)) - w.Header().Set("Content-Type", "application/json") - w.Write(b) -} - -// generateSelfSignedCert generates a self-signed cert/key pairs and writes to the certPath/keyPath. -// This method is mostly identical to crypto.GenerateSelfSignedCert except for the 'IsCA' and 'KeyUsage' -// in the certificate template. (Maybe we can merge these two methods). -func GenerateSelfSignedCert(t *testing.T, host, certPath, keyPath string) { - priv, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - t.Fatal(err) - } - - template := x509.Certificate{ - SerialNumber: big.NewInt(1), - Subject: pkix.Name{ - CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix()), - }, - NotBefore: time.Now(), - NotAfter: time.Now().Add(time.Hour * 24 * 365), - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - IsCA: true, - } - - if ip := net.ParseIP(host); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - } else { - template.DNSNames = append(template.DNSNames, host) - } - - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) - if err != nil { - t.Fatal(err) - } - - // Generate cert - certBuffer := bytes.Buffer{} - if err := pem.Encode(&certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { - t.Fatal(err) - } - - // Generate key - keyBuffer := bytes.Buffer{} - if err := pem.Encode(&keyBuffer, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil { - t.Fatal(err) - } - - // Write cert - if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(certPath, certBuffer.Bytes(), os.FileMode(0644)); err != nil { - t.Fatal(err) - } - - // Write key - if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(keyPath, keyBuffer.Bytes(), os.FileMode(0600)); err != nil { - t.Fatal(err) - } -}