diff --git a/.gitignore b/.gitignore index ef96cc88..0e4e30b7 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ bin .env .test.env *.pem +!github/actions/testdata/*.pem # OS .DS_STORE diff --git a/github/actions/client.go b/github/actions/client.go index f52d2b95..fe164330 100644 --- a/github/actions/client.go +++ b/github/actions/client.go @@ -3,6 +3,8 @@ package actions import ( "bytes" "context" + "crypto/tls" + "crypto/x509" "encoding/base64" "encoding/json" "fmt" @@ -70,6 +72,9 @@ type Client struct { githubConfigURL string logger logr.Logger userAgent string + + rootCAs *x509.CertPool + tlsInsecureSkipVerify bool } type ClientOption func(*Client) @@ -98,6 +103,18 @@ func WithRetryWaitMax(retryWaitMax time.Duration) ClientOption { } } +func WithRootCAs(rootCAs *x509.CertPool) ClientOption { + return func(c *Client) { + c.rootCAs = rootCAs + } +} + +func WithoutTLSVerify() ClientOption { + return func(c *Client) { + c.tlsInsecureSkipVerify = true + } +} + func NewClient(ctx context.Context, githubConfigURL string, creds *ActionsAuth, options ...ClientOption) (ActionsService, error) { ac := &Client{ creds: creds, @@ -121,6 +138,26 @@ func NewClient(ctx context.Context, githubConfigURL string, creds *ActionsAuth, retryClient.RetryMax = ac.retryMax retryClient.RetryWaitMax = ac.retryWaitMax + + transport, ok := retryClient.HTTPClient.Transport.(*http.Transport) + if !ok { + // this should always be true, because retryablehttp.NewClient() uses + // cleanhttp.DefaultPooledTransport() + return nil, fmt.Errorf("failed to get http transport from retryablehttp client") + } + if transport.TLSClientConfig == nil { + transport.TLSClientConfig = &tls.Config{} + } + + if ac.rootCAs != nil { + transport.TLSClientConfig.RootCAs = ac.rootCAs + } + + if ac.tlsInsecureSkipVerify { + transport.TLSClientConfig.InsecureSkipVerify = true + } + + retryClient.HTTPClient.Transport = transport ac.Client = retryClient.StandardClient() rt, err := ac.getRunnerRegistrationToken(ctx, githubConfigURL, *creds) @@ -776,7 +813,7 @@ func (c *Client) getRunnerRegistrationToken(ctx context.Context, githubConfigUrl c.logger.Info("getting runner registration token", "registrationTokenURL", registrationTokenURL) - resp, err := http.DefaultClient.Do(req) + resp, err := c.Do(req) if err != nil { return nil, err } @@ -832,7 +869,7 @@ func (c *Client) fetchAccessToken(ctx context.Context, gitHubConfigURL string, c c.logger.Info("getting access token for GitHub App auth", "accessTokenURL", accessTokenURL.String()) - resp, err := http.DefaultClient.Do(req) + resp, err := c.Do(req) if err != nil { return nil, err } @@ -892,7 +929,7 @@ func (c *Client) getActionsServiceAdminConnection(ctx context.Context, rt *regis c.logger.Info("getting Actions tenant URL and JWT", "registrationURL", registrationURL.String()) - resp, err := http.DefaultClient.Do(req) + resp, err := c.Do(req) if err != nil { return nil, err } diff --git a/github/actions/client_tls_test.go b/github/actions/client_tls_test.go new file mode 100644 index 00000000..320798b8 --- /dev/null +++ b/github/actions/client_tls_test.go @@ -0,0 +1,149 @@ +package actions_test + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "github.com/actions/actions-runner-controller/github/actions" + "github.com/golang-jwt/jwt/v4" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestServerWithSelfSignedCertificates(t *testing.T) { + ctx := context.Background() + + // this handler is a very very barebones replica of actions api + // used during the creation of a a new client + h := func(w http.ResponseWriter, r *http.Request) { + // handle get registration token + if strings.HasSuffix(r.URL.Path, "/runners/registration-token") { + w.WriteHeader(http.StatusCreated) + w.Write([]byte(`{"token":"token"}`)) + return + } + + // handle getActionsServiceAdminConnection + if strings.HasSuffix(r.URL.Path, "/actions/runner-registration") { + claims := &jwt.RegisteredClaims{ + IssuedAt: jwt.NewNumericDate(time.Now().Add(-1 * time.Minute)), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Minute)), + Issuer: "123", + } + + token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(samplePrivateKey)) + require.NoError(t, err) + tokenString, err := token.SignedString(privateKey) + require.NoError(t, err) + w.Write([]byte(`{"url":"TODO","token":"` + tokenString + `"}`)) + return + } + } + + certPath := filepath.Join("testdata", "server.crt") + keyPath := filepath.Join("testdata", "server.key") + + t.Run("client without ca certs", func(t *testing.T) { + server := startNewTLSTestServer(t, certPath, keyPath, http.HandlerFunc(h)) + configURL := server.URL + "/my-org" + + auth := &actions.ActionsAuth{ + Token: "token", + } + client, err := actions.NewClient(ctx, configURL, auth) + assert.Nil(t, client) + require.NotNil(t, err) + + if runtime.GOOS == "linux" { + assert.True(t, errors.As(err, &x509.UnknownAuthorityError{})) + } + + // on macOS we only get an untyped error from the system verifying the + // certificate + if runtime.GOOS == "darwin" { + assert.True(t, strings.HasSuffix(err.Error(), "certificate is not trusted")) + } + }) + + t.Run("client with ca certs", func(t *testing.T) { + server := startNewTLSTestServer(t, certPath, keyPath, http.HandlerFunc(h)) + configURL := server.URL + "/my-org" + + auth := &actions.ActionsAuth{ + Token: "token", + } + + cert, err := os.ReadFile(filepath.Join("testdata", "rootCA.crt")) + require.NoError(t, err) + + pool, err := actions.RootCAsFromConfigMap(map[string][]byte{"cert": cert}) + require.NoError(t, err) + + client, err := actions.NewClient(ctx, configURL, auth, actions.WithRootCAs(pool)) + require.NoError(t, err) + assert.NotNil(t, client) + }) + + t.Run("client with ca chain certs", func(t *testing.T) { + server := startNewTLSTestServer( + t, + filepath.Join("testdata", "leaf.pem"), + filepath.Join("testdata", "leaf.key"), + http.HandlerFunc(h), + ) + configURL := server.URL + "/my-org" + + auth := &actions.ActionsAuth{ + Token: "token", + } + + cert, err := os.ReadFile(filepath.Join("testdata", "intermediate.pem")) + require.NoError(t, err) + + pool, err := actions.RootCAsFromConfigMap(map[string][]byte{"cert": cert}) + require.NoError(t, err) + + client, err := actions.NewClient(ctx, configURL, auth, actions.WithRootCAs(pool), actions.WithRetryMax(0)) + require.NoError(t, err) + assert.NotNil(t, client) + }) + + t.Run("client skipping tls verification", func(t *testing.T) { + server := startNewTLSTestServer(t, certPath, keyPath, http.HandlerFunc(h)) + configURL := server.URL + "/my-org" + + auth := &actions.ActionsAuth{ + Token: "token", + } + + client, err := actions.NewClient(ctx, configURL, auth, actions.WithoutTLSVerify()) + require.NoError(t, err) + assert.NotNil(t, client) + }) +} + +func startNewTLSTestServer(t *testing.T, certPath, keyPath string, handler http.Handler) *httptest.Server { + server := httptest.NewUnstartedServer(handler) + t.Cleanup(func() { + server.Close() + }) + + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + require.NoError(t, err) + + server.TLS = &tls.Config{Certificates: []tls.Certificate{cert}} + server.StartTLS() + + return server +} diff --git a/github/actions/multi_client.go b/github/actions/multi_client.go index c7a53b74..85e0fa75 100644 --- a/github/actions/multi_client.go +++ b/github/actions/multi_client.go @@ -2,6 +2,7 @@ package actions import ( "context" + "crypto/x509" "fmt" "net/url" "strconv" @@ -168,3 +169,19 @@ func (m *multiClient) GetClientFromSecret(ctx context.Context, githubConfigURL, auth.AppCreds = &GitHubAppAuth{AppID: parsedAppID, AppInstallationID: parsedAppInstallationID, AppPrivateKey: appPrivateKey} return m.GetClientFor(ctx, githubConfigURL, auth, namespace) } + +func RootCAsFromConfigMap(configMapData map[string][]byte) (*x509.CertPool, error) { + caCertPool, err := x509.SystemCertPool() + if err != nil { + caCertPool = x509.NewCertPool() + } + + for key, certData := range configMapData { + ok := caCertPool.AppendCertsFromPEM(certData) + if !ok { + return nil, fmt.Errorf("no certificates successfully parsed from key %s", key) + } + } + + return caCertPool, nil +} diff --git a/github/actions/testdata/intermediate.pem b/github/actions/testdata/intermediate.pem new file mode 100644 index 00000000..527f5c2b --- /dev/null +++ b/github/actions/testdata/intermediate.pem @@ -0,0 +1,73 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 8 (0x8) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=arc-test, CN=localhost + Validity + Not Before: Jan 23 17:54:51 2023 GMT + Not After : Jun 9 17:54:51 2050 GMT + Subject: C=US, O=arc-test, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:dd:61:59:0a:19:19:1a:d4:e1:f1:c0:8d:bb:c2: + f8:32:e5:04:55:c5:ea:f6:71:5c:d3:ad:d0:b1:c3: + 86:73:ba:f1:01:7f:5d:45:6c:bf:0d:e6:27:c4:f0: + a0:f2:be:73:61:04:1f:f5:ca:3b:9d:11:c6:00:ae: + 49:6f:7f:9c:f7:e1:21:e4:53:aa:29:71:58:fe:e8: + c8:6c:25:2f:0a:ef:8f:be:e8:1c:9d:76:05:4a:28: + e1:88:20:4b:4a:51:59:48:3c:84:05:ec:10:ae:be: + 76:05:ee:ff:bf:54:67:02:e6:01:e8:02:b4:d0:07: + 79:39:10:71:e6:b1:25:b5:6a:24:7c:22:ef:70:90: + 5b:32:69:81:9d:34:82:a6:3b:fd:b5:8e:6b:8d:12: + e7:bd:0a:0d:61:1f:ed:16:82:30:f9:2c:93:8d:fe: + 70:b5:4d:c4:53:0b:5e:f1:ba:4a:c5:08:ba:56:8f: + dd:b7:fc:13:cd:1b:d1:1c:31:00:d1:7d:49:fd:54: + 4d:73:e8:73:1d:69:dd:98:53:fe:77:66:3f:05:a7: + 61:1c:e4:c2:a6:b9:31:df:c5:0b:b5:78:fc:7f:42: + 9f:0e:a6:1a:eb:59:46:be:ac:95:8a:85:ea:05:e4: + 8a:33:00:2e:8e:d9:a4:20:4a:39:77:53:16:7c:8a: + 9c:59 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign + Signature Algorithm: sha256WithRSAEncryption + a5:5c:2f:be:b7:e4:a8:e7:95:7a:58:93:be:5e:3a:5a:f7:0b: + 70:ba:8e:b8:a8:dc:7c:5b:2c:c1:5b:80:f3:8f:8a:c4:2b:d2: + ad:69:21:29:75:3a:5b:7d:bb:4f:2b:f9:27:4a:ab:d7:bd:05: + 0a:aa:50:e7:b0:2d:7f:05:2d:42:af:c1:de:aa:a1:69:b1:b4: + 78:ce:f2:78:98:97:49:c0:be:1b:5f:23:47:8d:c5:e8:c4:85: + 84:31:d0:5c:9b:12:96:43:08:ae:32:dc:9d:d4:ad:c6:6d:15: + ad:0f:6c:ec:50:61:86:3c:b7:75:90:6b:44:d5:dd:56:c1:11: + fe:6e:07:80:85:93:8a:34:da:e9:38:21:ac:ce:73:ce:c1:26: + 4e:94:2f:9b:82:b5:06:7a:ef:21:3a:80:79:89:c2:fd:e5:04: + 25:1c:a8:b2:28:91:1f:a1:91:b6:82:ea:ce:64:21:ef:da:0c: + af:bf:09:5a:e2:9f:5b:f6:0f:bf:cf:91:d3:97:7f:f1:25:9b: + 8b:5f:10:16:fb:a8:92:11:13:38:cb:32:02:03:69:6f:9e:fe: + 2a:b0:56:c7:49:f3:2a:9b:c6:ee:a2:98:25:d2:a0:c0:f3:c4: + 03:99:e1:94:e3:f5:95:28:07:ec:db:31:3a:25:79:c1:45:c8: + 8a:1e:75:39 +-----BEGIN CERTIFICATE----- +MIIDCDCCAfCgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA0MQswCQYDVQQGEwJVUzER +MA8GA1UECgwIYXJjLXRlc3QxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yMzAxMjMx +NzU0NTFaGA8yMDUwMDYwOTE3NTQ1MVowNDELMAkGA1UEBhMCVVMxETAPBgNVBAoM +CGFyYy10ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDdYVkKGRka1OHxwI27wvgy5QRVxer2cVzTrdCxw4ZzuvEB +f11FbL8N5ifE8KDyvnNhBB/1yjudEcYArklvf5z34SHkU6opcVj+6MhsJS8K74++ +6ByddgVKKOGIIEtKUVlIPIQF7BCuvnYF7v+/VGcC5gHoArTQB3k5EHHmsSW1aiR8 +Iu9wkFsyaYGdNIKmO/21jmuNEue9Cg1hH+0WgjD5LJON/nC1TcRTC17xukrFCLpW +j923/BPNG9EcMQDRfUn9VE1z6HMdad2YU/53Zj8Fp2Ec5MKmuTHfxQu1ePx/Qp8O +phrrWUa+rJWKheoF5IozAC6O2aQgSjl3UxZ8ipxZAgMBAAGjIzAhMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4IBAQClXC++ +t+So55V6WJO+Xjpa9wtwuo64qNx8WyzBW4Dzj4rEK9KtaSEpdTpbfbtPK/knSqvX +vQUKqlDnsC1/BS1Cr8HeqqFpsbR4zvJ4mJdJwL4bXyNHjcXoxIWEMdBcmxKWQwiu +Mtyd1K3GbRWtD2zsUGGGPLd1kGtE1d1WwRH+bgeAhZOKNNrpOCGsznPOwSZOlC+b +grUGeu8hOoB5icL95QQlHKiyKJEfoZG2gurOZCHv2gyvvwla4p9b9g+/z5HTl3/x +JZuLXxAW+6iSERM4yzICA2lvnv4qsFbHSfMqm8buopgl0qDA88QDmeGU4/WVKAfs +2zE6JXnBRciKHnU5 +-----END CERTIFICATE----- diff --git a/github/actions/testdata/leaf.key b/github/actions/testdata/leaf.key new file mode 100644 index 00000000..b479990f --- /dev/null +++ b/github/actions/testdata/leaf.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEApgzbb+dY2DKM+Ysrk+l7guhvtgY9q5ws7pqF0duYkI2zmyMW +EDSkXKPoODiimYhol4Cr7c6hgtOzZS0+W4kVdhDLpk/mg9a4ZTLJqn2DIHj9Q0G+ +ENJrENjxPHfykXcXs2LAgRLffle4g4bfnJVQCyzZNiCblpqTnSSyEFa1AEtrxq6r +2E/bYjBm18G4WxBOWHukuYsZ5FKlgzT/ZNeLoME9WDp4+wxKAEGSnEhlPv/Sr6ns +GxPz5i9NPBFqg373oDW17Nxere7M6l6oMqNtFbsQafI7Jmy4rrgHBrDf0s1SlaY3 +ceDPwXpT9ttHXZe9Dqb6MSEEQvL4IWG0TEGMJwIDAQABAoIBADfl8CEVslTlf4uq +C/t5B/kjoieWpkAVDRMttYrV7+AJs8Kv5weBkSsWimASwLoKr5sA19/wRXKzLZsL +xggud6kNMmFEWIddSynWFQltwyy1ThzMDt2+2AgN3/fJMUFC5BmhTsikv9PaV+T/ +DFu77/wzFtQf2gCy/KpT5hWV+sykDBriswFoVycUbC2kAcxcaTJioB5TKmNQoxxe +pUxiQSaEgVYTAuKt5da1UqBmiqoqNUQNIC+Q7T6cGw6F6WPd6sF13VXHF3EU/Q+6 +6bW1p+9iuDxAa6sWI5gLCYFq4vcgTvqa5tGSsrxw7CNmuZFc/HtjMqAcBGDAKwFI +zrTW8sECgYEA2XxoucFX81P+AW6C2ymHCH+4BUdLYANkAE5VLkiTvGN9NCqYmdQD +5jb1yE3dp0YmDvZ/ZGJpwrJHwU7r1FNt1psRpPhIyErzk7MxgF0Efa4dRl3c2rno +aTWgWSTXB1UU3+ev157P3vGNJEewCCgMwdp4qv9dVu+mGaJTZWAKNnECgYEAw3Sj +9bV1c5uaoPvMNAIBVFeSL3W9A6A90uPcPyu55NAsEHtZgAd8JFSYnT2rwbND1CC8 +YqynWfvAEyXshVeBEurRC13XCXhB6U3rfEFnLA5+HZsCgpFNfKHiNvxfVGsGGTRn +YKGYAPOHz1jN8TVT3ZwzKNc5olzVB4KP97ylKBcCgYEApqqHWurG6qsQOaqlzyw4 +1hOCQ1FKew6+INnmvyxRQwp/FW4bOa9XOaIeolzBowHIAql2IMimQdT71jET2sgA +oXh+ggzfQdbmaObm5XbjDSlUN+uQZ3IWoCG/evEXdAAImjnj8Ho81J4JyqbBSM7g +T+KLnIdL0WafxH84J7T8vpECgYBYJZ5cDX3uqVpPB7/MJKtc0jGHXd3kaLv5A/Is +OxgW7RsyQ67VYorGB7DcGRgAv0vzut+60IqYtkSlXhERAamgUm38ZlG4X5e6E/4D +h6tz3wVZbLLxF36OmqNekOqdM7cIXu3QUpAuvaWeCTq3cYllBDC+VnITmzIntOYg +n98L+QKBgF4AQDN4Mcet9RSFVdgK2Ue11ngr39SUUQapsK7uFvRZhv86voeDR3zv +4zaj5JIemaRAOMnJS0pdHBHoz4tcqeDcqqHAdliZ/DYmiFhm8Q6Jufzc0KBkus6p +w8/pSBRpjZQZrgQZxYoU1g9Smy94ysY4DHt5BZIWGbBiwaREARYO +-----END RSA PRIVATE KEY----- diff --git a/github/actions/testdata/leaf.pem b/github/actions/testdata/leaf.pem new file mode 100644 index 00000000..a87d3be4 --- /dev/null +++ b/github/actions/testdata/leaf.pem @@ -0,0 +1,81 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 11 (0xb) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=arc-test, CN=localhost + Validity + Not Before: Jan 23 17:54:52 2023 GMT + Not After : Jun 9 17:54:52 2050 GMT + Subject: C=US, O=actions-runner-controller, OU=actions-runner-controller test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:a6:0c:db:6f:e7:58:d8:32:8c:f9:8b:2b:93:e9: + 7b:82:e8:6f:b6:06:3d:ab:9c:2c:ee:9a:85:d1:db: + 98:90:8d:b3:9b:23:16:10:34:a4:5c:a3:e8:38:38: + a2:99:88:68:97:80:ab:ed:ce:a1:82:d3:b3:65:2d: + 3e:5b:89:15:76:10:cb:a6:4f:e6:83:d6:b8:65:32: + c9:aa:7d:83:20:78:fd:43:41:be:10:d2:6b:10:d8: + f1:3c:77:f2:91:77:17:b3:62:c0:81:12:df:7e:57: + b8:83:86:df:9c:95:50:0b:2c:d9:36:20:9b:96:9a: + 93:9d:24:b2:10:56:b5:00:4b:6b:c6:ae:ab:d8:4f: + db:62:30:66:d7:c1:b8:5b:10:4e:58:7b:a4:b9:8b: + 19:e4:52:a5:83:34:ff:64:d7:8b:a0:c1:3d:58:3a: + 78:fb:0c:4a:00:41:92:9c:48:65:3e:ff:d2:af:a9: + ec:1b:13:f3:e6:2f:4d:3c:11:6a:83:7e:f7:a0:35: + b5:ec:dc:5e:ad:ee:cc:ea:5e:a8:32:a3:6d:15:bb: + 10:69:f2:3b:26:6c:b8:ae:b8:07:06:b0:df:d2:cd: + 52:95:a6:37:71:e0:cf:c1:7a:53:f6:db:47:5d:97: + bd:0e:a6:fa:31:21:04:42:f2:f8:21:61:b4:4c:41: + 8c:27 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + DirName:/C=US/O=arc-test/CN=localhost + serial:08 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment + X509v3 Subject Alternative Name: + IP Address:127.0.0.1, DNS:localhost + Signature Algorithm: sha256WithRSAEncryption + 73:70:5c:40:cf:48:a9:c0:8b:50:c8:10:b5:3c:57:18:fd:ac: + 05:6b:7c:8f:ad:b2:cc:2a:92:b8:70:57:19:88:40:b6:b1:d9: + e7:44:7b:44:69:4b:dc:10:20:08:a8:5a:b3:29:3c:ce:42:f8: + 57:04:e4:9b:b6:d8:22:0f:d4:4a:51:76:b8:32:4b:b6:bd:b9: + 10:4a:69:b6:20:f3:77:2b:eb:7b:11:b3:c9:1d:96:a6:0d:9a: + 29:ae:e6:89:91:95:26:29:7a:a9:e9:8f:6e:9c:aa:17:96:e7: + 87:04:84:bb:61:38:a8:d3:f7:2e:ef:ce:49:38:e7:d9:2c:86: + be:a8:63:98:6a:f2:62:4f:48:1a:ee:d0:3f:9c:33:1e:d2:b3: + 3d:3c:bd:ab:4d:a9:c0:02:d2:ae:01:f4:fb:dd:1d:10:82:08: + 26:d2:06:2c:c1:5a:3c:76:c6:85:b8:c4:22:63:7d:c1:40:c5: + 44:bf:ac:b9:6e:58:ac:5b:5e:5f:34:08:a7:08:88:14:10:3f: + 3d:5d:6e:9c:38:d6:9c:2d:45:88:3f:46:10:15:bd:2f:d5:75: + 5f:cc:cb:f3:e7:56:c2:d9:99:7b:a9:ea:a8:b5:ff:60:35:28: + b9:0c:6b:13:0b:d9:e0:d1:89:11:9b:4b:26:ad:2e:5a:93:ea: + 56:00:da:a0 +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIBCzANBgkqhkiG9w0BAQsFADA0MQswCQYDVQQGEwJVUzER +MA8GA1UECgwIYXJjLXRlc3QxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yMzAxMjMx +NzU0NTJaGA8yMDUwMDYwOTE3NTQ1MlowWjELMAkGA1UEBhMCVVMxIjAgBgNVBAoM +GWFjdGlvbnMtcnVubmVyLWNvbnRyb2xsZXIxJzAlBgNVBAsMHmFjdGlvbnMtcnVu +bmVyLWNvbnRyb2xsZXIgdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKYM22/nWNgyjPmLK5Ppe4Lob7YGPaucLO6ahdHbmJCNs5sjFhA0pFyj6Dg4 +opmIaJeAq+3OoYLTs2UtPluJFXYQy6ZP5oPWuGUyyap9gyB4/UNBvhDSaxDY8Tx3 +8pF3F7NiwIES335XuIOG35yVUAss2TYgm5aak50kshBWtQBLa8auq9hP22IwZtfB +uFsQTlh7pLmLGeRSpYM0/2TXi6DBPVg6ePsMSgBBkpxIZT7/0q+p7BsT8+YvTTwR +aoN+96A1tezcXq3uzOpeqDKjbRW7EGnyOyZsuK64Bwaw39LNUpWmN3Hgz8F6U/bb +R12XvQ6m+jEhBELy+CFhtExBjCcCAwEAAaN+MHwwRgYDVR0jBD8wPaE4pDYwNDEL +MAkGA1UEBhMCVVMxETAPBgNVBAoMCGFyYy10ZXN0MRIwEAYDVQQDDAlsb2NhbGhv +c3SCAQgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwGgYDVR0RBBMwEYcEfwAAAYIJ +bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQBzcFxAz0ipwItQyBC1PFcY/awF +a3yPrbLMKpK4cFcZiEC2sdnnRHtEaUvcECAIqFqzKTzOQvhXBOSbttgiD9RKUXa4 +Mku2vbkQSmm2IPN3K+t7EbPJHZamDZopruaJkZUmKXqp6Y9unKoXlueHBIS7YTio +0/cu785JOOfZLIa+qGOYavJiT0ga7tA/nDMe0rM9PL2rTanAAtKuAfT73R0Qgggm +0gYswVo8dsaFuMQiY33BQMVEv6y5blisW15fNAinCIgUED89XW6cONacLUWIP0YQ +Fb0v1XVfzMvz51bC2Zl7qeqotf9gNSi5DGsTC9ng0YkRm0smrS5ak+pWANqg +-----END CERTIFICATE----- diff --git a/github/actions/testdata/rootCA.crt b/github/actions/testdata/rootCA.crt new file mode 100644 index 00000000..7c9c7bbc --- /dev/null +++ b/github/actions/testdata/rootCA.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdICCQCoZFduxPa/eDANBgkqhkiG9w0BAQsFADA2MQswCQYDVQQGEwJV +UzEnMCUGA1UEAwweYWN0aW9ucy1ydW5uZXItY29udHJvbGxlci10ZXN0MCAXDTIz +MDExOTE2NTAwMVoYDzIwNTAwNjA1MTY1MDAxWjA2MQswCQYDVQQGEwJVUzEnMCUG +A1UEAwweYWN0aW9ucy1ydW5uZXItY29udHJvbGxlci10ZXN0MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAykHCU0I/pdzhnQBwr2N+7so66LPq0cxc8JJL +S2mmk7gg+NWhTZzoci6aYXNRKCyH6B2Wmy7Qveku2wqT2+/4JBMYgTWH5bF7yt76 +LB+x9YruSgH/pBN2WI4vRU87NOAU8F0o0U/Lp5vAJoRo+ePPvcHu0OY1WF+QnEX+ +xtp6gJFGf5DT4U9upwEgQjKgvKFEoB5KNeH1qr2fS2yA2vhm6Uhm+1i/KUQUZ49K +GvFK8TQQT4HXft8rPLP5M9OitdqVU8SX0dQoXZ4M41/qydycHOvApj0LlH/XsicZ +x0mkF90hD+9VRqeYFe562NI4NHR7FGP7HKPWibNjXKC2w+z+aQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQBxaOCnmakd1PPp+pH40OjUktKG1nqM2tGqP0o3Bk7huB2y +jXIDi9ETuTeqqHONwwgsKOVY3J+Zt5R+teBSC0qUnypODzu+9v8Xa4Is9G9GyT5S +erjpPcJjQnvZyMHLH9DGGWE9UCyqKIqmaEc9bwr2oz1+a0rsaS3ZdIFlQibBHij5 +tdJcnzXfN4T4GIbYXKMCOYDy/5CiNJ26l/pQNpO9JCzsEmngw0ooS0Bi8EcTCgB6 +dsHl0w8va3l1kvxWWIlNTGwrAEpRbXmL01hAqx2yCiaFPVZ/eRNWmBWO4LpW4ouK +YOaA+X7geM6XVFlZE3cP58AxYKWHGAThxkZbD5cu +-----END CERTIFICATE----- diff --git a/github/actions/testdata/server.crt b/github/actions/testdata/server.crt new file mode 100644 index 00000000..be71271a --- /dev/null +++ b/github/actions/testdata/server.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDnTCCAoWgAwIBAgIJAJskDVhiEY6fMA0GCSqGSIb3DQEBCwUAMDYxCzAJBgNV +BAYTAlVTMScwJQYDVQQDDB5hY3Rpb25zLXJ1bm5lci1jb250cm9sbGVyLXRlc3Qw +HhcNMjMwMTE5MTY1MTE0WhcNMjQwMTE5MTY1MTE0WjBaMQswCQYDVQQGEwJVUzEi +MCAGA1UECgwZYWN0aW9ucy1ydW5uZXItY29udHJvbGxlcjEnMCUGA1UECwweYWN0 +aW9ucy1ydW5uZXItY29udHJvbGxlciB0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAzOTt1/VjuaHzn+b7jLeufW3rxLHFKQV+LiUiT389rbFGY+DN +CC+Nzx+DbFBpKcX/scseVhFzlXlrESWWZ4h7LGMXRsTDKs91F1RMuFCd8eIEwbuV +civR44IqT5r/0hlMOWemd3Fh/c8KF+9dWQ0q0T3tvlVzEbWNRTVAXTT4JzizqNd1 +1hhnuV/KjhiptPC/8jQ4D9ocZKM8a1pM9O2z3bnmH7VTQJkhjxE7gefQTPQRmvKk +C7uqvfk2NHTTnKiLfkE10JhLTa0VND2aofNWCybGTyHNNCNlepakoP3KyFC2LjPR +oR5iwSnCRDu1z8tDWW+rIa3pfxdQ8LnH4J4CDwIDAQABo4GJMIGGMFAGA1UdIwRJ +MEehOqQ4MDYxCzAJBgNVBAYTAlVTMScwJQYDVQQDDB5hY3Rpb25zLXJ1bm5lci1j +b250cm9sbGVyLXRlc3SCCQCoZFduxPa/eDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE +8DAaBgNVHREEEzARhwR/AAABgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEB +ALdl0ytjellmhtjbXkUZKAl/R2ZXMAVxIOtb4qiN6OOwOMK4p2Wt26p34bQa2JD0 +t0qvesI7spQzQObNMdT6NZJl8Ul0ABuzti/Esvmby+VfsFPasCQVXx+jqGhERqXc +SeZFIVWVACyfAc1dkqfGwehSrY62eBlY2PJ1JezagW6aLAnV6Si+96++mkALJDdX +MZhhSqjxM+Nnmhpy4My6oHVrdYWHcuVhzlEmNaMtmJCYuihIyD2Usn32xJK1k89d +WgEOPCk+ZDAligPlGZS201fsznJk5uIjmxPjjFlJLXotBs8H7j0cQ2JkV5YHsHCk +EYf5EJ0ZKtZbwRFeRC1Ajxg= +-----END CERTIFICATE----- diff --git a/github/actions/testdata/server.key b/github/actions/testdata/server.key new file mode 100644 index 00000000..f7011fd4 --- /dev/null +++ b/github/actions/testdata/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzOTt1/VjuaHzn+b7jLeufW3rxLHFKQV+LiUiT389rbFGY+DN +CC+Nzx+DbFBpKcX/scseVhFzlXlrESWWZ4h7LGMXRsTDKs91F1RMuFCd8eIEwbuV +civR44IqT5r/0hlMOWemd3Fh/c8KF+9dWQ0q0T3tvlVzEbWNRTVAXTT4JzizqNd1 +1hhnuV/KjhiptPC/8jQ4D9ocZKM8a1pM9O2z3bnmH7VTQJkhjxE7gefQTPQRmvKk +C7uqvfk2NHTTnKiLfkE10JhLTa0VND2aofNWCybGTyHNNCNlepakoP3KyFC2LjPR +oR5iwSnCRDu1z8tDWW+rIa3pfxdQ8LnH4J4CDwIDAQABAoIBAC5rr3c+IVntV0Tj +EBrRgrboMIJfxEuG8w+BWkSoj1DK2SfHxqwUGgzTFvNzRGAye7vMSRM24Pj8iUVZ +Pro2MbHcwWlHKvCID/85GiioGyCyFGHQHgu/4c2pr+xZMZxoHtzintRw28KlJaRG +lt+WHB1L6pE0yt04RMlpRyvW1GIODtEh1wya61Aa2xZMJxgbNWv89znLI2f3ForY +QR/he8hQtfJQeH+mv2SvJ1bopkJ58ZObKapuJAWCSxzVRj/yol1MqfUDBy4NrJfY +F5UP0BSmnED1EdIXeC0duo5RyiSfHqqJlcKR+zlepOb4pr4I1H8P6AIJ9iiunxUJ +h9i+YAECgYEA7JgrH5sjStcHdwUgEPN4E1MI3WRwDnnuVpzeSUH7tRqK4lsdIKmF +u/ss3TMwTgC8XR4JJbVp+6ea54zpVjtBGwShMSvn2+e7OHHg1YoVqBIgRpL+/C4m +wfon2EglQ0IjscUtKuAR/UyhU6vZtkYRUKeXRKisW4yoobdob0Y4lakCgYEA3bMl +BfszC5c0RXI5vsBUBvr9gXMY/8tacM7H8i3vT7JqoYJG6GGST0/HeK+La3w2zryx +Q8IL6uLy/HZvTHZ+BSp4KzwwgDUIk0jm/JcvzD2ZhJHoAo4aQTc6QI2ZNgjGVwCb +nJ0Niaxc4CdSUEAUHH1bCXk/e2stcnieFuiiPPcCgYAIxrA60OdjPEyzloYU+uMG +XHskszgQ4Wb84X7BWug6VIy4Tsbq0j76tRt57Q8qpY5XKekO9AbFZfcyBaEWKMaG +eQp9p3JHTvY75sV/Rkr9XAbEd2lr805OvbfCpxJyxz5JttWxFHS2X6RQVTyTLVAx +HLZYvqT+FF6g+QuvrPwmWQKBgAQspVvReQqU1EUie3feAzcGbtOLKUNXvuI04orq +1oC3qU5VN6SUgb7Aj87z7zoc4qNN5kCSXMsVbuHWEQ5thL3wKMcXoQoo9Xpgewjy +h9Herw9R9/5kUpY7xfsFL4dW7vUga82tH14iQrVtyBz+t+I5cgdhoxJd2EM5hjCE +PNnNAoGBALPjmvEZ1HJdCOxY/AisziVtOFc6Glk/KhpSIT7WE1me4qLQFmrsHIDQ +kZ8Sb1f3PQ4T4vHGrtl8qh144MJPI1Nb8klzdlD1xeypGpgXoQb5fsC17g1fgczp +TGzq3pvnlGnrgVmnfrWQCHXDLzXtLqM/Pu84guPFftJQ+++yy0np +-----END RSA PRIVATE KEY-----