mirror of https://github.com/grafana/loki
feat: Upgrade `golang.org/x/oauth2` to 0.27.0 (#16960)
parent
28fc3f4f45
commit
fb70d0305f
@ -1,202 +0,0 @@ |
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "[]" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright [yyyy] [name of copyright owner] |
||||
|
||||
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. |
@ -1,18 +0,0 @@ |
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// 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 internal |
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "1.20.1" |
@ -1,23 +0,0 @@ |
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This file, and the {{.RootMod}} import, won't actually become part of
|
||||
// the resultant binary.
|
||||
//go:build modhack
|
||||
// +build modhack
|
||||
|
||||
package metadata |
||||
|
||||
// Necessary for safely adding multi-module repo. See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
||||
import _ "cloud.google.com/go/compute/internal" |
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
generated
vendored
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
generated
vendored
Binary file not shown.
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
generated
vendored
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
generated
vendored
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der
generated
vendored
Binary file not shown.
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem
generated
vendored
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem
generated
vendored
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 |
||||
a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 |
||||
OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 |
||||
RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK |
||||
P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 |
||||
HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu |
||||
0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 |
||||
EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 |
||||
/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA |
||||
QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ |
||||
nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD |
||||
X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco |
||||
pKklVz0= |
||||
-----END CERTIFICATE----- |
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem
generated
vendored
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem
generated
vendored
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF |
||||
l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj |
||||
+Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G |
||||
4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA |
||||
xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh |
||||
68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ |
||||
/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL |
||||
Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA |
||||
VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 |
||||
9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH |
||||
MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt |
||||
aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq |
||||
xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx |
||||
2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv |
||||
EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z |
||||
aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq |
||||
udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs |
||||
VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm |
||||
56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT |
||||
GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V |
||||
Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm |
||||
HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q |
||||
BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH |
||||
qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh |
||||
GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= |
||||
-----END RSA PRIVATE KEY----- |
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der
generated
vendored
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der
generated
vendored
Binary file not shown.
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem
generated
vendored
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem
generated
vendored
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT |
||||
fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ |
||||
qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE |
||||
xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es |
||||
Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 |
||||
Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM |
||||
ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR |
||||
e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X |
||||
POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl |
||||
AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg |
||||
odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ |
||||
PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN |
||||
Dhm6uZM= |
||||
-----END CERTIFICATE----- |
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem
generated
vendored
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem
generated
vendored
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs |
||||
8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO |
||||
QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk |
||||
XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA |
||||
Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc |
||||
gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf |
||||
LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl |
||||
jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 |
||||
4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q |
||||
Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P |
||||
nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 |
||||
drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE |
||||
duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 |
||||
L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG |
||||
06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm |
||||
eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD |
||||
uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 |
||||
lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL |
||||
a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb |
||||
hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ |
||||
7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j |
||||
r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 |
||||
eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD |
||||
B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz |
||||
7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== |
||||
-----END RSA PRIVATE KEY----- |
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 |
||||
a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 |
||||
OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 |
||||
RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK |
||||
P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 |
||||
HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu |
||||
0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 |
||||
EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 |
||||
/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA |
||||
QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ |
||||
nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD |
||||
X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco |
||||
pKklVz0= |
||||
-----END CERTIFICATE----- |
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF |
||||
l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj |
||||
+Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G |
||||
4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA |
||||
xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh |
||||
68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ |
||||
/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL |
||||
Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA |
||||
VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 |
||||
9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH |
||||
MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt |
||||
aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq |
||||
xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx |
||||
2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv |
||||
EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z |
||||
aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq |
||||
udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs |
||||
VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm |
||||
56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT |
||||
GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V |
||||
Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm |
||||
HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q |
||||
BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH |
||||
qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh |
||||
GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= |
||||
-----END RSA PRIVATE KEY----- |
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT |
||||
fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ |
||||
qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE |
||||
xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es |
||||
Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 |
||||
Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM |
||||
ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR |
||||
e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X |
||||
POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl |
||||
AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg |
||||
odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ |
||||
PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN |
||||
Dhm6uZM= |
||||
-----END CERTIFICATE----- |
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs |
||||
8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO |
||||
QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk |
||||
XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA |
||||
Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc |
||||
gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf |
||||
LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl |
||||
jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 |
||||
4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q |
||||
Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P |
||||
nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 |
||||
drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE |
||||
duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 |
||||
L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG |
||||
06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm |
||||
eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD |
||||
uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 |
||||
lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL |
||||
a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb |
||||
hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ |
||||
7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j |
||||
r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 |
||||
eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD |
||||
B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz |
||||
7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== |
||||
-----END RSA PRIVATE KEY----- |
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem
generated
vendored
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem
generated
vendored
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 |
||||
a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 |
||||
OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 |
||||
RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK |
||||
P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 |
||||
HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu |
||||
0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 |
||||
EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 |
||||
/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA |
||||
QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ |
||||
nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD |
||||
X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco |
||||
pKklVz0= |
||||
-----END CERTIFICATE----- |
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem
generated
vendored
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem
generated
vendored
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF |
||||
l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj |
||||
+Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G |
||||
4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA |
||||
xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh |
||||
68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ |
||||
/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL |
||||
Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA |
||||
VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 |
||||
9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH |
||||
MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt |
||||
aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq |
||||
xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx |
||||
2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv |
||||
EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z |
||||
aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq |
||||
udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs |
||||
VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm |
||||
56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT |
||||
GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V |
||||
Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm |
||||
HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q |
||||
BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH |
||||
qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh |
||||
GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= |
||||
-----END RSA PRIVATE KEY----- |
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem
generated
vendored
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem
generated
vendored
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT |
||||
fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ |
||||
qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE |
||||
xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es |
||||
Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 |
||||
Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM |
||||
ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR |
||||
e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X |
||||
POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl |
||||
AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg |
||||
odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ |
||||
PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN |
||||
Dhm6uZM= |
||||
-----END CERTIFICATE----- |
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem
generated
vendored
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem
generated
vendored
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs |
||||
8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO |
||||
QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk |
||||
XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA |
||||
Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc |
||||
gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf |
||||
LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl |
||||
jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 |
||||
4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q |
||||
Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P |
||||
nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 |
||||
drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE |
||||
duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 |
||||
L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG |
||||
06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm |
||||
eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD |
||||
uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 |
||||
lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL |
||||
a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb |
||||
hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ |
||||
7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j |
||||
r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 |
||||
eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD |
||||
B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz |
||||
7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== |
||||
-----END RSA PRIVATE KEY----- |
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKXNlBRVe6UepjQUijIFPZBd/4qYwDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwMzE1WhcNNDIwNTI2MjAwMzE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAOOFuIucH7XXfohGxKd3uR/ihUA/LdduR9I8kfpUEbq5BOt8xZe5/Yn9 |
||||
a1ozEHVW6cOAbHbnwAR8tkSgZ/t42QIA2k77HWU1Jh2xiEIsJivo3imm4/kZWuR0 |
||||
OqPh7MhzxpR/hvNwpI5mJsAVBWFMa5KtecFZLnyZtwHylrRN1QXzuLrOxuKFufK3 |
||||
RKbTABScn5RbZL976H/jgfSeXrbt242NrIoBnVe6fRbekbq2DQ6zFArbQMUgHjHK |
||||
P0UqBgdr1QmHfi9KytFyx9BTP3gXWnWIu+bY7/v7qKJMHFwGETo+dCLWYevJL316 |
||||
HnLfhApDMfP8U+Yv/y1N/YvgaSOSlEcCAwEAAaNTMFEwHQYDVR0OBBYEFKhAU4nu |
||||
0h/lrnggbIGvx4ej0WklMB8GA1UdIwQYMBaAFKhAU4nu0h/lrnggbIGvx4ej0Wkl |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE/6NghzQ5fu6yR6 |
||||
EHKbj/YMrFdT7aGn5n2sAf7wJ33LIhiFHkpWBsVlm7rDtZtwhe891ZK/P60anlg9 |
||||
/P0Ua53tSRVRmCvTnEbXWOVMN4is6MsR7BlmzUxl4AtIn7jbeifEwRL7B4xDYmdA |
||||
QrQnsqoz45dLgS5xK4WDqXATP09Q91xQDuhud/b+A4jrvgwFASmL7rMIZbp4f1JQ |
||||
nlnl/9VoTBQBvJiWkDUtQDMpRLtauddEkv4AGz75p5IspXWD6cOemuh2iQec11xD |
||||
X20rs2WZbAcAiUa3nmy8OKYw435vmpj8gp39WYbX/Yx9TymrFFbVY92wYn+quTco |
||||
pKklVz0= |
||||
-----END CERTIFICATE----- |
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEogIBAAKCAQEA44W4i5wftdd+iEbEp3e5H+KFQD8t125H0jyR+lQRurkE63zF |
||||
l7n9if1rWjMQdVbpw4BsdufABHy2RKBn+3jZAgDaTvsdZTUmHbGIQiwmK+jeKabj |
||||
+Rla5HQ6o+HsyHPGlH+G83CkjmYmwBUFYUxrkq15wVkufJm3AfKWtE3VBfO4us7G |
||||
4oW58rdEptMAFJyflFtkv3vof+OB9J5etu3bjY2sigGdV7p9Ft6RurYNDrMUCttA |
||||
xSAeMco/RSoGB2vVCYd+L0rK0XLH0FM/eBdadYi75tjv+/uookwcXAYROj50ItZh |
||||
68kvfXoect+ECkMx8/xT5i//LU39i+BpI5KURwIDAQABAoIBABgyjo/6iLzUMFbZ |
||||
/+w3pW6orrdIgN2akvTfED9pVYFgUA+jc3hRhY95bkNnjuaL2cy7Cc4Tk65mfRQL |
||||
Y0OxdJLr+EvSFSxAXM9npDA1ddHRsF8JqtFBSxNk8R+g1Yf0GDiO35Fgd3/ViWWA |
||||
VtQkRoSRApP3oiQKTRZd8H04keFR+PvmDk/Lq11l3Kc24A1PevKIPX1oI990ggw9 |
||||
9i4uSV+cnuMxmcI9xxJtgwdDFdjr39l2arLOHr4s6LGoV2IOdXHNlv5xRqWUZ0FH |
||||
MDHowkLgwDrdSTnNeaVNkce14Gqx+bd4hNaLCdKXMpedBTEmrut3f3hdV1kKjaKt |
||||
aqRYr8ECgYEA/YDGZY2jvFoHHBywlqmEMFrrCvQGH51m5R1Ntpkzr+Rh3YCmrpvq |
||||
xgwJXING0PUw3dz+xrH5lJICrfNE5Kt3fPu1rAEy+13mYsNowghtUq2Rtu0Hsjjx |
||||
2E3Bf8vEB6RNBMmGkUpTTIAroGF5tpJoRvfnWax+k4pFdrKYFtyZdNcCgYEA5cNv |
||||
EPltvOobjTXlUmtVP3n27KZN2aXexTcagLzRxE9CV4cYySENl3KuOMmccaZpIl6z |
||||
aHk6BT4X+M0LqElNUczrInfVqI+SGAFLGy7W6CJaqSr6cpyFUP/fosKpm6wKGgLq |
||||
udHfpvz5rckhKd8kJxFLvhGOK9yN5qpzih0gfhECgYAJfwRvk3G5wYmYpP58dlcs |
||||
VIuPenqsPoI3PPTHTU/hW+XKnWIhElgmGRdUrto9Q6IT/Y5RtSMLTLjq+Tzwb/fm |
||||
56rziYv2XJsfwgAvnI8z1Kqrto9ePsHYf3krJ1/thVsZPc9bq/QY3ohD1sLvcuaT |
||||
GgBBnLOVJU3a12/ZE2RwOwKBgF0csWMAoj8/5IB6if+3ral2xOGsl7oPZVMo/J2V |
||||
Z7EVqb4M6rd/pKFugTpUQgkwtkSOekhpcGD1hAN5HTNK2YG/+L5UMAsKe9sskwJm |
||||
HgOfAHy0BSDzW3ey6i9skg2bT9Cww+0gJ3Hl7U1HSCBO5LjMYpSZSrNtwzfqdb5Q |
||||
BX3xAoGARZdR28Ej3+/+0+fz47Yu2h4z0EI/EbrudLOWY936jIeAVwHckI3+BuqH |
||||
qR4poj1gfbnMxNuI9UzIXzjEmGewx9kDZ7IYnvloZKqoVQODO5GlKF2ja6IcMNlh |
||||
GCNdD6PSAS6HcmalmWo9sj+1YMkrl+GJikKZqVBHrHNwMGAG67w= |
||||
-----END RSA PRIVATE KEY----- |
@ -1,24 +0,0 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIID8TCCAtmgAwIBAgIUKCoDuLtiZXvhsBY2RoDm0ugizJ8wDQYJKoZIhvcNAQEL |
||||
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2 |
||||
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE |
||||
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN |
||||
MjIwNTMxMjAwODI1WhcNNDIwNTI2MjAwODI1WjCBhzELMAkGA1UEBhMCVVMxCzAJ |
||||
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx |
||||
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ |
||||
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC |
||||
AQoCggEBAKK1++PXQ+M3hjYH/v0K4UEYl5ljzpNM1i52eQM+gFooojT87PDSaphT |
||||
fs0PXy/PTAjHBEvPhWpOpmQXfJNYzjwcCvg66hbqkv++/VTZiFLAsHagzkEz+FRJ |
||||
qT5Eq7G5FLyw1izX1uxyPN7tAEWEEg7eqsiaXD3Cq8+TYN9cjirPeF7RZF8yFCYE |
||||
xqvbo+Yc6RL6xw19iXVTfctRgQe581KQuIY5/LXo3dWDEilFdsADAe8XAEcO64es |
||||
Ow0g1UvXLnpXSE151kXBFb3sKH/ZjCecDYMCIMEb4sWLSblkSxJ5sNSmXIG4wtr2 |
||||
Qnii7CXZgnVYraQE/Jyh+NMQANuoSdMCAwEAAaNTMFEwHQYDVR0OBBYEFAyQQQuM |
||||
ab+YUQqjK8dVVOoHVFmXMB8GA1UdIwQYMBaAFAyQQQuMab+YUQqjK8dVVOoHVFmX |
||||
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADj0vQ6ykWhicoqR |
||||
e6VZMwlEJV7/DSvWWKBd9MUjfKye0A4565ya5lmnzP3DiD3nqGe3miqmLsXKDs+X |
||||
POqlPXTWIamP7D4MJ32XtSLwZB4ru+I+Ao/P/VngPepoRPQoBnzHe7jww0rokqxl |
||||
AZERjlbTUwUAy/BPWPSzSJZ2j0tcs6ZLDNyYzpK4ao8R9/1VmQ92Tcp3feJs1QTg |
||||
odRQc3om/AkWOwsll+oyX0UbJeHkFHiLanUPXbdh+/BkSvZJ8ynL+feSDdaurPe+ |
||||
PSfnqLtQft9/neecGRdEaQzzzSFVQUVQzTdK1Q7hA7b55b2HvIa3ktDiks+sJsYN |
||||
Dhm6uZM= |
||||
-----END CERTIFICATE----- |
@ -1,27 +0,0 @@ |
||||
-----BEGIN RSA PRIVATE KEY----- |
||||
MIIEpAIBAAKCAQEAorX749dD4zeGNgf+/QrhQRiXmWPOk0zWLnZ5Az6AWiiiNPzs |
||||
8NJqmFN+zQ9fL89MCMcES8+Fak6mZBd8k1jOPBwK+DrqFuqS/779VNmIUsCwdqDO |
||||
QTP4VEmpPkSrsbkUvLDWLNfW7HI83u0ARYQSDt6qyJpcPcKrz5Ng31yOKs94XtFk |
||||
XzIUJgTGq9uj5hzpEvrHDX2JdVN9y1GBB7nzUpC4hjn8tejd1YMSKUV2wAMB7xcA |
||||
Rw7rh6w7DSDVS9cueldITXnWRcEVvewof9mMJ5wNgwIgwRvixYtJuWRLEnmw1KZc |
||||
gbjC2vZCeKLsJdmCdVitpAT8nKH40xAA26hJ0wIDAQABAoIBACaNR+lsD8G+XiZf |
||||
LqN1+HkcAo9tfnyYMAdCOtnx7SdviT9Uzi8hK/B7mAeuJLeHPlS2EuaDfPD7QaFl |
||||
jza6S+MiIdc+3kgfvESsVAnOoOY6kZUJ9NSuI6CU82y1iJjLaYZrv9NQMLRFPPb0 |
||||
4KOX709mosB1EnXvshW0rbc+jtDFhrm1SxMt+k9TuzmMxjbOeW4LOLXPgU8X1T3Q |
||||
Xy0hMZZtcgBs9wFIo8yCtmOixax9pnFE8rRltgDxTodn9LLdz1FieyntNgDksZ0P |
||||
nt4kV7Mqly7ELaea+Foaj244mKsesic2e3GhAlMRLun/VSunSf7mOCxfpITB8dp1 |
||||
drDhOYECgYEA19151dVxRcviuovN6Dar+QszMTnU8pDJ8BjLFjXjP/hNBBwMTHDE |
||||
duMuWk2qnwZqMooI/shxrF/ufmTgS0CFrh2+ANBZu27vWConJNXcyNtdigI4wt50 |
||||
L0Y2qcZn2mg67qFXHwoR3QNwrwnPwEjRXA09at9CSRZzcwDQ0ETXhYsCgYEAwPaG |
||||
06QdK8Zyly7TTzZJwxzv9uGiqzodmGtX6NEKjgij2JaCxHpukqZBJoqa0jKeK1cm |
||||
eNVkOvT5ff9TMzarSHQLr3pZen2/oVLb5gaFkbcJt/klv9Fd+ZRilHY3i6QwS6pD |
||||
uMiPOWS4DrLHDRVoVlAZTDjT1RVwwTs+P2NhJdkCgYEAsriXysbxBYyMp05gqEW7 |
||||
lHIFbFgpSrs9th+Q5U6wW6JEgYaHWDJ1NslY80MiZI93FWjbkbZ7BvBWESeL3EIL |
||||
a+EMErht0pVCbIhZ6FF4foPAqia0wAJVx14mm+G80kNBp5jE/NnleEsE3KcO7nBb |
||||
hg8gLn+x7bk81JZ0TDrzBYkCgYEAuQKluv47SeF3tSScTfKLPpvcKCWmxe1uutkQ |
||||
7JShPhVioyOMNb39jnYBOWbjkm4d4QgqRuiytSR0oi3QI+Ziy5EYMyNn713qAk9j |
||||
r2TJZDDPDKnBW+zt4YI4EohWMXk3JRUW4XDKggjjwJQA7bZ812TtHHvP/xoThfG7 |
||||
eSNb3eECgYBw6ssgCtMrdvQiEmjKVX/9yI38mvC2kSGyzbrQnGUfgqRGomRpeZuD |
||||
B5E3kysA4td5pT5lvcLgSW0TbOz+YbiriXjwOihPIelCvc9gE2eOUI71/byUWPFz |
||||
7u5F/xQ4NaGr5suLF+lBC6h7pSbM4El9lIHQAQadpuEdzHqrw+hs3g== |
||||
-----END RSA PRIVATE KEY----- |
@ -0,0 +1,198 @@ |
||||
package oauth2 |
||||
|
||||
import ( |
||||
"context" |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"io" |
||||
"net/http" |
||||
"net/url" |
||||
"strings" |
||||
"time" |
||||
|
||||
"golang.org/x/oauth2/internal" |
||||
) |
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
||||
const ( |
||||
errAuthorizationPending = "authorization_pending" |
||||
errSlowDown = "slow_down" |
||||
errAccessDenied = "access_denied" |
||||
errExpiredToken = "expired_token" |
||||
) |
||||
|
||||
// DeviceAuthResponse describes a successful RFC 8628 Device Authorization Response
|
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
||||
type DeviceAuthResponse struct { |
||||
// DeviceCode
|
||||
DeviceCode string `json:"device_code"` |
||||
// UserCode is the code the user should enter at the verification uri
|
||||
UserCode string `json:"user_code"` |
||||
// VerificationURI is where user should enter the user code
|
||||
VerificationURI string `json:"verification_uri"` |
||||
// VerificationURIComplete (if populated) includes the user code in the verification URI. This is typically shown to the user in non-textual form, such as a QR code.
|
||||
VerificationURIComplete string `json:"verification_uri_complete,omitempty"` |
||||
// Expiry is when the device code and user code expire
|
||||
Expiry time.Time `json:"expires_in,omitempty"` |
||||
// Interval is the duration in seconds that Poll should wait between requests
|
||||
Interval int64 `json:"interval,omitempty"` |
||||
} |
||||
|
||||
func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) { |
||||
type Alias DeviceAuthResponse |
||||
var expiresIn int64 |
||||
if !d.Expiry.IsZero() { |
||||
expiresIn = int64(time.Until(d.Expiry).Seconds()) |
||||
} |
||||
return json.Marshal(&struct { |
||||
ExpiresIn int64 `json:"expires_in,omitempty"` |
||||
*Alias |
||||
}{ |
||||
ExpiresIn: expiresIn, |
||||
Alias: (*Alias)(&d), |
||||
}) |
||||
|
||||
} |
||||
|
||||
func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error { |
||||
type Alias DeviceAuthResponse |
||||
aux := &struct { |
||||
ExpiresIn int64 `json:"expires_in"` |
||||
// workaround misspelling of verification_uri
|
||||
VerificationURL string `json:"verification_url"` |
||||
*Alias |
||||
}{ |
||||
Alias: (*Alias)(c), |
||||
} |
||||
if err := json.Unmarshal(data, &aux); err != nil { |
||||
return err |
||||
} |
||||
if aux.ExpiresIn != 0 { |
||||
c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn)) |
||||
} |
||||
if c.VerificationURI == "" { |
||||
c.VerificationURI = aux.VerificationURL |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// DeviceAuth returns a device auth struct which contains a device code
|
||||
// and authorization information provided for users to enter on another device.
|
||||
func (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) { |
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.1
|
||||
v := url.Values{ |
||||
"client_id": {c.ClientID}, |
||||
} |
||||
if len(c.Scopes) > 0 { |
||||
v.Set("scope", strings.Join(c.Scopes, " ")) |
||||
} |
||||
for _, opt := range opts { |
||||
opt.setValue(v) |
||||
} |
||||
return retrieveDeviceAuth(ctx, c, v) |
||||
} |
||||
|
||||
func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) { |
||||
if c.Endpoint.DeviceAuthURL == "" { |
||||
return nil, errors.New("endpoint missing DeviceAuthURL") |
||||
} |
||||
|
||||
req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode())) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
||||
req.Header.Set("Accept", "application/json") |
||||
|
||||
t := time.Now() |
||||
r, err := internal.ContextClient(ctx).Do(req) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20)) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("oauth2: cannot auth device: %v", err) |
||||
} |
||||
if code := r.StatusCode; code < 200 || code > 299 { |
||||
return nil, &RetrieveError{ |
||||
Response: r, |
||||
Body: body, |
||||
} |
||||
} |
||||
|
||||
da := &DeviceAuthResponse{} |
||||
err = json.Unmarshal(body, &da) |
||||
if err != nil { |
||||
return nil, fmt.Errorf("unmarshal %s", err) |
||||
} |
||||
|
||||
if !da.Expiry.IsZero() { |
||||
// Make a small adjustment to account for time taken by the request
|
||||
da.Expiry = da.Expiry.Add(-time.Since(t)) |
||||
} |
||||
|
||||
return da, nil |
||||
} |
||||
|
||||
// DeviceAccessToken polls the server to exchange a device code for a token.
|
||||
func (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) { |
||||
if !da.Expiry.IsZero() { |
||||
var cancel context.CancelFunc |
||||
ctx, cancel = context.WithDeadline(ctx, da.Expiry) |
||||
defer cancel() |
||||
} |
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
|
||||
v := url.Values{ |
||||
"client_id": {c.ClientID}, |
||||
"grant_type": {"urn:ietf:params:oauth:grant-type:device_code"}, |
||||
"device_code": {da.DeviceCode}, |
||||
} |
||||
if len(c.Scopes) > 0 { |
||||
v.Set("scope", strings.Join(c.Scopes, " ")) |
||||
} |
||||
for _, opt := range opts { |
||||
opt.setValue(v) |
||||
} |
||||
|
||||
// "If no value is provided, clients MUST use 5 as the default."
|
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
|
||||
interval := da.Interval |
||||
if interval == 0 { |
||||
interval = 5 |
||||
} |
||||
|
||||
ticker := time.NewTicker(time.Duration(interval) * time.Second) |
||||
defer ticker.Stop() |
||||
for { |
||||
select { |
||||
case <-ctx.Done(): |
||||
return nil, ctx.Err() |
||||
case <-ticker.C: |
||||
tok, err := retrieveToken(ctx, c, v) |
||||
if err == nil { |
||||
return tok, nil |
||||
} |
||||
|
||||
e, ok := err.(*RetrieveError) |
||||
if !ok { |
||||
return nil, err |
||||
} |
||||
switch e.ErrorCode { |
||||
case errSlowDown: |
||||
// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
|
||||
// "the interval MUST be increased by 5 seconds for this and all subsequent requests"
|
||||
interval += 5 |
||||
ticker.Reset(time.Duration(interval) * time.Second) |
||||
case errAuthorizationPending: |
||||
// Do nothing.
|
||||
case errAccessDenied, errExpiredToken: |
||||
fallthrough |
||||
default: |
||||
return tok, err |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,78 +0,0 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
// This file applies to App Engine first generation runtimes (<= Go 1.9).
|
||||
|
||||
package google |
||||
|
||||
import ( |
||||
"context" |
||||
"sort" |
||||
"strings" |
||||
"sync" |
||||
|
||||
"golang.org/x/oauth2" |
||||
"google.golang.org/appengine" |
||||
) |
||||
|
||||
func init() { |
||||
appengineTokenFunc = appengine.AccessToken |
||||
appengineAppIDFunc = appengine.AppID |
||||
} |
||||
|
||||
// See comment on AppEngineTokenSource in appengine.go.
|
||||
func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { |
||||
scopes := append([]string{}, scope...) |
||||
sort.Strings(scopes) |
||||
return &gaeTokenSource{ |
||||
ctx: ctx, |
||||
scopes: scopes, |
||||
key: strings.Join(scopes, " "), |
||||
} |
||||
} |
||||
|
||||
// aeTokens helps the fetched tokens to be reused until their expiration.
|
||||
var ( |
||||
aeTokensMu sync.Mutex |
||||
aeTokens = make(map[string]*tokenLock) // key is space-separated scopes
|
||||
) |
||||
|
||||
type tokenLock struct { |
||||
mu sync.Mutex // guards t; held while fetching or updating t
|
||||
t *oauth2.Token |
||||
} |
||||
|
||||
type gaeTokenSource struct { |
||||
ctx context.Context |
||||
scopes []string |
||||
key string // to aeTokens map; space-separated scopes
|
||||
} |
||||
|
||||
func (ts *gaeTokenSource) Token() (*oauth2.Token, error) { |
||||
aeTokensMu.Lock() |
||||
tok, ok := aeTokens[ts.key] |
||||
if !ok { |
||||
tok = &tokenLock{} |
||||
aeTokens[ts.key] = tok |
||||
} |
||||
aeTokensMu.Unlock() |
||||
|
||||
tok.mu.Lock() |
||||
defer tok.mu.Unlock() |
||||
if tok.t.Valid() { |
||||
return tok.t, nil |
||||
} |
||||
access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
tok.t = &oauth2.Token{ |
||||
AccessToken: access, |
||||
Expiry: exp, |
||||
} |
||||
return tok.t, nil |
||||
} |
@ -1,28 +0,0 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !appengine
|
||||
// +build !appengine
|
||||
|
||||
// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible.
|
||||
|
||||
package google |
||||
|
||||
import ( |
||||
"context" |
||||
"log" |
||||
"sync" |
||||
|
||||
"golang.org/x/oauth2" |
||||
) |
||||
|
||||
var logOnce sync.Once // only spam about deprecation once
|
||||
|
||||
// See comment on AppEngineTokenSource in appengine.go.
|
||||
func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { |
||||
logOnce.Do(func() { |
||||
log.Print("google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.") |
||||
}) |
||||
return ComputeTokenSource("") |
||||
} |
@ -0,0 +1,517 @@ |
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/* |
||||
Package externalaccount provides support for creating workload identity |
||||
federation and workforce identity federation token sources that can be |
||||
used to access Google Cloud resources from external identity providers. |
||||
|
||||
# Workload Identity Federation |
||||
|
||||
Using workload identity federation, your application can access Google Cloud |
||||
resources from Amazon Web Services (AWS), Microsoft Azure or any identity |
||||
provider that supports OpenID Connect (OIDC) or SAML 2.0. |
||||
Traditionally, applications running outside Google Cloud have used service |
||||
account keys to access Google Cloud resources. Using identity federation, |
||||
you can allow your workload to impersonate a service account. |
||||
This lets you access Google Cloud resources directly, eliminating the |
||||
maintenance and security burden associated with service account keys. |
||||
|
||||
Follow the detailed instructions on how to configure Workload Identity Federation |
||||
in various platforms: |
||||
|
||||
Amazon Web Services (AWS): https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds#aws
|
||||
Microsoft Azure: https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds#azure
|
||||
OIDC identity provider: https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers#oidc
|
||||
SAML 2.0 identity provider: https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers#saml
|
||||
|
||||
For OIDC and SAML providers, the library can retrieve tokens in fours ways: |
||||
from a local file location (file-sourced credentials), from a server |
||||
(URL-sourced credentials), from a local executable (executable-sourced |
||||
credentials), or from a user defined function that returns an OIDC or SAML token. |
||||
For file-sourced credentials, a background process needs to be continuously |
||||
refreshing the file location with a new OIDC/SAML token prior to expiration. |
||||
For tokens with one hour lifetimes, the token needs to be updated in the file |
||||
every hour. The token can be stored directly as plain text or in JSON format. |
||||
For URL-sourced credentials, a local server needs to host a GET endpoint to |
||||
return the OIDC/SAML token. The response can be in plain text or JSON. |
||||
Additional required request headers can also be specified. |
||||
For executable-sourced credentials, an application needs to be available to |
||||
output the OIDC/SAML token and other information in a JSON format. |
||||
For more information on how these work (and how to implement |
||||
executable-sourced credentials), please check out: |
||||
https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers#create_a_credential_configuration
|
||||
|
||||
To use a custom function to supply the token, define a struct that implements the [SubjectTokenSupplier] interface for OIDC/SAML providers, |
||||
or one that implements [AwsSecurityCredentialsSupplier] for AWS providers. This can then be used when building a [Config]. |
||||
The [golang.org/x/oauth2.TokenSource] created from the config using [NewTokenSource] can then be used to access Google |
||||
Cloud resources. For instance, you can create a new client from the |
||||
[cloud.google.com/go/storage] package and pass in option.WithTokenSource(yourTokenSource)) |
||||
|
||||
Note that this library does not perform any validation on the token_url, token_info_url, |
||||
or service_account_impersonation_url fields of the credential configuration. |
||||
It is not recommended to use a credential configuration that you did not generate with |
||||
the gcloud CLI unless you verify that the URL fields point to a googleapis.com domain. |
||||
|
||||
# Workforce Identity Federation |
||||
|
||||
Workforce identity federation lets you use an external identity provider (IdP) to |
||||
authenticate and authorize a workforce—a group of users, such as employees, partners, |
||||
and contractors—using IAM, so that the users can access Google Cloud services. |
||||
Workforce identity federation extends Google Cloud's identity capabilities to support |
||||
syncless, attribute-based single sign on. |
||||
|
||||
With workforce identity federation, your workforce can access Google Cloud resources |
||||
using an external identity provider (IdP) that supports OpenID Connect (OIDC) or |
||||
SAML 2.0 such as Azure Active Directory (Azure AD), Active Directory Federation |
||||
Services (AD FS), Okta, and others. |
||||
|
||||
Follow the detailed instructions on how to configure Workload Identity Federation |
||||
in various platforms: |
||||
|
||||
Azure AD: https://cloud.google.com/iam/docs/workforce-sign-in-azure-ad
|
||||
Okta: https://cloud.google.com/iam/docs/workforce-sign-in-okta
|
||||
OIDC identity provider: https://cloud.google.com/iam/docs/configuring-workforce-identity-federation#oidc
|
||||
SAML 2.0 identity provider: https://cloud.google.com/iam/docs/configuring-workforce-identity-federation#saml
|
||||
|
||||
For workforce identity federation, the library can retrieve tokens in four ways: |
||||
from a local file location (file-sourced credentials), from a server |
||||
(URL-sourced credentials), from a local executable (executable-sourced |
||||
credentials), or from a user supplied function that returns an OIDC or SAML token. |
||||
For file-sourced credentials, a background process needs to be continuously |
||||
refreshing the file location with a new OIDC/SAML token prior to expiration. |
||||
For tokens with one hour lifetimes, the token needs to be updated in the file |
||||
every hour. The token can be stored directly as plain text or in JSON format. |
||||
For URL-sourced credentials, a local server needs to host a GET endpoint to |
||||
return the OIDC/SAML token. The response can be in plain text or JSON. |
||||
Additional required request headers can also be specified. |
||||
For executable-sourced credentials, an application needs to be available to |
||||
output the OIDC/SAML token and other information in a JSON format. |
||||
For more information on how these work (and how to implement |
||||
executable-sourced credentials), please check out: |
||||
https://cloud.google.com/iam/docs/workforce-obtaining-short-lived-credentials#generate_a_configuration_file_for_non-interactive_sign-in
|
||||
|
||||
To use a custom function to supply the token, define a struct that implements the [SubjectTokenSupplier] interface for OIDC/SAML providers. |
||||
This can then be used when building a [Config]. |
||||
The [golang.org/x/oauth2.TokenSource] created from the config using [NewTokenSource] can then be used access Google |
||||
Cloud resources. For instance, you can create a new client from the |
||||
[cloud.google.com/go/storage] package and pass in option.WithTokenSource(yourTokenSource)) |
||||
|
||||
# Security considerations |
||||
|
||||
Note that this library does not perform any validation on the token_url, token_info_url, |
||||
or service_account_impersonation_url fields of the credential configuration. |
||||
It is not recommended to use a credential configuration that you did not generate with |
||||
the gcloud CLI unless you verify that the URL fields point to a googleapis.com domain. |
||||
*/ |
||||
package externalaccount |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"net/http" |
||||
"regexp" |
||||
"strconv" |
||||
"strings" |
||||
"time" |
||||
|
||||
"golang.org/x/oauth2" |
||||
"golang.org/x/oauth2/google/internal/impersonate" |
||||
"golang.org/x/oauth2/google/internal/stsexchange" |
||||
) |
||||
|
||||
const ( |
||||
universeDomainPlaceholder = "UNIVERSE_DOMAIN" |
||||
defaultTokenURL = "https://sts.UNIVERSE_DOMAIN/v1/token" |
||||
defaultUniverseDomain = "googleapis.com" |
||||
) |
||||
|
||||
// now aliases time.Now for testing
|
||||
var now = func() time.Time { |
||||
return time.Now().UTC() |
||||
} |
||||
|
||||
// Config stores the configuration for fetching tokens with external credentials.
|
||||
type Config struct { |
||||
// Audience is the Secure Token Service (STS) audience which contains the resource name for the workload
|
||||
// identity pool or the workforce pool and the provider identifier in that pool. Required.
|
||||
Audience string |
||||
// SubjectTokenType is the STS token type based on the Oauth2.0 token exchange spec.
|
||||
// Expected values include:
|
||||
// “urn:ietf:params:oauth:token-type:jwt”
|
||||
// “urn:ietf:params:oauth:token-type:id-token”
|
||||
// “urn:ietf:params:oauth:token-type:saml2”
|
||||
// “urn:ietf:params:aws:token-type:aws4_request”
|
||||
// Required.
|
||||
SubjectTokenType string |
||||
// TokenURL is the STS token exchange endpoint. If not provided, will default to
|
||||
// https://sts.UNIVERSE_DOMAIN/v1/token, with UNIVERSE_DOMAIN set to the
|
||||
// default service domain googleapis.com unless UniverseDomain is set.
|
||||
// Optional.
|
||||
TokenURL string |
||||
// TokenInfoURL is the token_info endpoint used to retrieve the account related information (
|
||||
// user attributes like account identifier, eg. email, username, uid, etc). This is
|
||||
// needed for gCloud session account identification. Optional.
|
||||
TokenInfoURL string |
||||
// ServiceAccountImpersonationURL is the URL for the service account impersonation request. This is only
|
||||
// required for workload identity pools when APIs to be accessed have not integrated with UberMint. Optional.
|
||||
ServiceAccountImpersonationURL string |
||||
// ServiceAccountImpersonationLifetimeSeconds is the number of seconds the service account impersonation
|
||||
// token will be valid for. If not provided, it will default to 3600. Optional.
|
||||
ServiceAccountImpersonationLifetimeSeconds int |
||||
// ClientSecret is currently only required if token_info endpoint also
|
||||
// needs to be called with the generated GCP access token. When provided, STS will be
|
||||
// called with additional basic authentication using ClientId as username and ClientSecret as password. Optional.
|
||||
ClientSecret string |
||||
// ClientID is only required in conjunction with ClientSecret, as described above. Optional.
|
||||
ClientID string |
||||
// CredentialSource contains the necessary information to retrieve the token itself, as well
|
||||
// as some environmental information. One of SubjectTokenSupplier, AWSSecurityCredentialSupplier or
|
||||
// CredentialSource must be provided. Optional.
|
||||
CredentialSource *CredentialSource |
||||
// QuotaProjectID is injected by gCloud. If the value is non-empty, the Auth libraries
|
||||
// will set the x-goog-user-project header which overrides the project associated with the credentials. Optional.
|
||||
QuotaProjectID string |
||||
// Scopes contains the desired scopes for the returned access token. Optional.
|
||||
Scopes []string |
||||
// WorkforcePoolUserProject is the workforce pool user project number when the credential
|
||||
// corresponds to a workforce pool and not a workload identity pool.
|
||||
// The underlying principal must still have serviceusage.services.use IAM
|
||||
// permission to use the project for billing/quota. Optional.
|
||||
WorkforcePoolUserProject string |
||||
// SubjectTokenSupplier is an optional token supplier for OIDC/SAML credentials.
|
||||
// One of SubjectTokenSupplier, AWSSecurityCredentialSupplier or CredentialSource must be provided. Optional.
|
||||
SubjectTokenSupplier SubjectTokenSupplier |
||||
// AwsSecurityCredentialsSupplier is an AWS Security Credential supplier for AWS credentials.
|
||||
// One of SubjectTokenSupplier, AWSSecurityCredentialSupplier or CredentialSource must be provided. Optional.
|
||||
AwsSecurityCredentialsSupplier AwsSecurityCredentialsSupplier |
||||
// UniverseDomain is the default service domain for a given Cloud universe.
|
||||
// This value will be used in the default STS token URL. The default value
|
||||
// is "googleapis.com". It will not be used if TokenURL is set. Optional.
|
||||
UniverseDomain string |
||||
} |
||||
|
||||
var ( |
||||
validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`) |
||||
) |
||||
|
||||
func validateWorkforceAudience(input string) bool { |
||||
return validWorkforceAudiencePattern.MatchString(input) |
||||
} |
||||
|
||||
// NewTokenSource Returns an external account TokenSource using the provided external account config.
|
||||
func NewTokenSource(ctx context.Context, conf Config) (oauth2.TokenSource, error) { |
||||
if conf.Audience == "" { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: Audience must be set") |
||||
} |
||||
if conf.SubjectTokenType == "" { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: Subject token type must be set") |
||||
} |
||||
if conf.WorkforcePoolUserProject != "" { |
||||
valid := validateWorkforceAudience(conf.Audience) |
||||
if !valid { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: Workforce pool user project should not be set for non-workforce pool credentials") |
||||
} |
||||
} |
||||
count := 0 |
||||
if conf.CredentialSource != nil { |
||||
count++ |
||||
} |
||||
if conf.SubjectTokenSupplier != nil { |
||||
count++ |
||||
} |
||||
if conf.AwsSecurityCredentialsSupplier != nil { |
||||
count++ |
||||
} |
||||
if count == 0 { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: One of CredentialSource, SubjectTokenSupplier, or AwsSecurityCredentialsSupplier must be set") |
||||
} |
||||
if count > 1 { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: Only one of CredentialSource, SubjectTokenSupplier, or AwsSecurityCredentialsSupplier must be set") |
||||
} |
||||
return conf.tokenSource(ctx, "https") |
||||
} |
||||
|
||||
// tokenSource is a private function that's directly called by some of the tests,
|
||||
// because the unit test URLs are mocked, and would otherwise fail the
|
||||
// validity check.
|
||||
func (c *Config) tokenSource(ctx context.Context, scheme string) (oauth2.TokenSource, error) { |
||||
|
||||
ts := tokenSource{ |
||||
ctx: ctx, |
||||
conf: c, |
||||
} |
||||
if c.ServiceAccountImpersonationURL == "" { |
||||
return oauth2.ReuseTokenSource(nil, ts), nil |
||||
} |
||||
scopes := c.Scopes |
||||
ts.conf.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"} |
||||
imp := impersonate.ImpersonateTokenSource{ |
||||
Ctx: ctx, |
||||
URL: c.ServiceAccountImpersonationURL, |
||||
Scopes: scopes, |
||||
Ts: oauth2.ReuseTokenSource(nil, ts), |
||||
TokenLifetimeSeconds: c.ServiceAccountImpersonationLifetimeSeconds, |
||||
} |
||||
return oauth2.ReuseTokenSource(nil, imp), nil |
||||
} |
||||
|
||||
// Subject token file types.
|
||||
const ( |
||||
fileTypeText = "text" |
||||
fileTypeJSON = "json" |
||||
) |
||||
|
||||
// Format contains information needed to retireve a subject token for URL or File sourced credentials.
|
||||
type Format struct { |
||||
// Type should be either "text" or "json". This determines whether the file or URL sourced credentials
|
||||
// expect a simple text subject token or if the subject token will be contained in a JSON object.
|
||||
// When not provided "text" type is assumed.
|
||||
Type string `json:"type"` |
||||
// SubjectTokenFieldName is only required for JSON format. This is the field name that the credentials will check
|
||||
// for the subject token in the file or URL response. This would be "access_token" for azure.
|
||||
SubjectTokenFieldName string `json:"subject_token_field_name"` |
||||
} |
||||
|
||||
// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange.
|
||||
type CredentialSource struct { |
||||
// File is the location for file sourced credentials.
|
||||
// One field amongst File, URL, Executable, or EnvironmentID should be provided, depending on the kind of credential in question.
|
||||
//
|
||||
// Important: If you accept a credential configuration (credential
|
||||
// JSON/File/Stream) from an external source for authentication to Google
|
||||
// Cloud Platform, you must validate it before providing it to any Google
|
||||
// API or library. Providing an unvalidated credential configuration to
|
||||
// Google APIs can compromise the security of your systems and data. For
|
||||
// more information, refer to [Validate credential configurations from
|
||||
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
|
||||
File string `json:"file"` |
||||
|
||||
// Url is the URL to call for URL sourced credentials.
|
||||
// One field amongst File, URL, Executable, or EnvironmentID should be provided, depending on the kind of credential in question.
|
||||
//
|
||||
// Important: If you accept a credential configuration (credential
|
||||
// JSON/File/Stream) from an external source for authentication to Google
|
||||
// Cloud Platform, you must validate it before providing it to any Google
|
||||
// API or library. Providing an unvalidated credential configuration to
|
||||
// Google APIs can compromise the security of your systems and data. For
|
||||
// more information, refer to [Validate credential configurations from
|
||||
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
|
||||
URL string `json:"url"` |
||||
// Headers are the headers to attach to the request for URL sourced credentials.
|
||||
Headers map[string]string `json:"headers"` |
||||
|
||||
// Executable is the configuration object for executable sourced credentials.
|
||||
// One field amongst File, URL, Executable, or EnvironmentID should be provided, depending on the kind of credential in question.
|
||||
//
|
||||
// Important: If you accept a credential configuration (credential
|
||||
// JSON/File/Stream) from an external source for authentication to Google
|
||||
// Cloud Platform, you must validate it before providing it to any Google
|
||||
// API or library. Providing an unvalidated credential configuration to
|
||||
// Google APIs can compromise the security of your systems and data. For
|
||||
// more information, refer to [Validate credential configurations from
|
||||
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
|
||||
Executable *ExecutableConfig `json:"executable"` |
||||
|
||||
// EnvironmentID is the EnvironmentID used for AWS sourced credentials. This should start with "AWS".
|
||||
// One field amongst File, URL, Executable, or EnvironmentID should be provided, depending on the kind of credential in question.
|
||||
//
|
||||
// Important: If you accept a credential configuration (credential
|
||||
// JSON/File/Stream) from an external source for authentication to Google
|
||||
// Cloud Platform, you must validate it before providing it to any Google
|
||||
// API or library. Providing an unvalidated credential configuration to
|
||||
// Google APIs can compromise the security of your systems and data. For
|
||||
// more information, refer to [Validate credential configurations from
|
||||
// external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials).
|
||||
EnvironmentID string `json:"environment_id"` |
||||
// RegionURL is the metadata URL to retrieve the region from for EC2 AWS credentials.
|
||||
RegionURL string `json:"region_url"` |
||||
// RegionalCredVerificationURL is the AWS regional credential verification URL, will default to
|
||||
// "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15" if not provided."
|
||||
RegionalCredVerificationURL string `json:"regional_cred_verification_url"` |
||||
// IMDSv2SessionTokenURL is the URL to retrieve the session token when using IMDSv2 in AWS.
|
||||
IMDSv2SessionTokenURL string `json:"imdsv2_session_token_url"` |
||||
// Format is the format type for the subject token. Used for File and URL sourced credentials. Expected values are "text" or "json".
|
||||
Format Format `json:"format"` |
||||
} |
||||
|
||||
// ExecutableConfig contains information needed for executable sourced credentials.
|
||||
type ExecutableConfig struct { |
||||
// Command is the the full command to run to retrieve the subject token.
|
||||
// This can include arguments. Must be an absolute path for the program. Required.
|
||||
Command string `json:"command"` |
||||
// TimeoutMillis is the timeout duration, in milliseconds. Defaults to 30000 milliseconds when not provided. Optional.
|
||||
TimeoutMillis *int `json:"timeout_millis"` |
||||
// OutputFile is the absolute path to the output file where the executable will cache the response.
|
||||
// If specified the auth libraries will first check this location before running the executable. Optional.
|
||||
OutputFile string `json:"output_file"` |
||||
} |
||||
|
||||
// SubjectTokenSupplier can be used to supply a subject token to exchange for a GCP access token.
|
||||
type SubjectTokenSupplier interface { |
||||
// SubjectToken should return a valid subject token or an error.
|
||||
// The external account token source does not cache the returned subject token, so caching
|
||||
// logic should be implemented in the supplier to prevent multiple requests for the same subject token.
|
||||
SubjectToken(ctx context.Context, options SupplierOptions) (string, error) |
||||
} |
||||
|
||||
// AWSSecurityCredentialsSupplier can be used to supply AwsSecurityCredentials and an AWS Region to
|
||||
// exchange for a GCP access token.
|
||||
type AwsSecurityCredentialsSupplier interface { |
||||
// AwsRegion should return the AWS region or an error.
|
||||
AwsRegion(ctx context.Context, options SupplierOptions) (string, error) |
||||
// AwsSecurityCredentials should return a valid set of AwsSecurityCredentials or an error.
|
||||
// The external account token source does not cache the returned security credentials, so caching
|
||||
// logic should be implemented in the supplier to prevent multiple requests for the same security credentials.
|
||||
AwsSecurityCredentials(ctx context.Context, options SupplierOptions) (*AwsSecurityCredentials, error) |
||||
} |
||||
|
||||
// SupplierOptions contains information about the requested subject token or AWS security credentials from the
|
||||
// Google external account credential.
|
||||
type SupplierOptions struct { |
||||
// Audience is the requested audience for the external account credential.
|
||||
Audience string |
||||
// Subject token type is the requested subject token type for the external account credential. Expected values include:
|
||||
// “urn:ietf:params:oauth:token-type:jwt”
|
||||
// “urn:ietf:params:oauth:token-type:id-token”
|
||||
// “urn:ietf:params:oauth:token-type:saml2”
|
||||
// “urn:ietf:params:aws:token-type:aws4_request”
|
||||
SubjectTokenType string |
||||
} |
||||
|
||||
// tokenURL returns the default STS token endpoint with the configured universe
|
||||
// domain.
|
||||
func (c *Config) tokenURL() string { |
||||
if c.UniverseDomain == "" { |
||||
return strings.Replace(defaultTokenURL, universeDomainPlaceholder, defaultUniverseDomain, 1) |
||||
} |
||||
return strings.Replace(defaultTokenURL, universeDomainPlaceholder, c.UniverseDomain, 1) |
||||
} |
||||
|
||||
// parse determines the type of CredentialSource needed.
|
||||
func (c *Config) parse(ctx context.Context) (baseCredentialSource, error) { |
||||
//set Defaults
|
||||
if c.TokenURL == "" { |
||||
c.TokenURL = c.tokenURL() |
||||
} |
||||
supplierOptions := SupplierOptions{Audience: c.Audience, SubjectTokenType: c.SubjectTokenType} |
||||
|
||||
if c.AwsSecurityCredentialsSupplier != nil { |
||||
awsCredSource := awsCredentialSource{ |
||||
awsSecurityCredentialsSupplier: c.AwsSecurityCredentialsSupplier, |
||||
targetResource: c.Audience, |
||||
supplierOptions: supplierOptions, |
||||
ctx: ctx, |
||||
} |
||||
return awsCredSource, nil |
||||
} else if c.SubjectTokenSupplier != nil { |
||||
return programmaticRefreshCredentialSource{subjectTokenSupplier: c.SubjectTokenSupplier, supplierOptions: supplierOptions, ctx: ctx}, nil |
||||
} else if len(c.CredentialSource.EnvironmentID) > 3 && c.CredentialSource.EnvironmentID[:3] == "aws" { |
||||
if awsVersion, err := strconv.Atoi(c.CredentialSource.EnvironmentID[3:]); err == nil { |
||||
if awsVersion != 1 { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: aws version '%d' is not supported in the current build", awsVersion) |
||||
} |
||||
|
||||
awsCredSource := awsCredentialSource{ |
||||
environmentID: c.CredentialSource.EnvironmentID, |
||||
regionURL: c.CredentialSource.RegionURL, |
||||
regionalCredVerificationURL: c.CredentialSource.RegionalCredVerificationURL, |
||||
credVerificationURL: c.CredentialSource.URL, |
||||
targetResource: c.Audience, |
||||
ctx: ctx, |
||||
} |
||||
if c.CredentialSource.IMDSv2SessionTokenURL != "" { |
||||
awsCredSource.imdsv2SessionTokenURL = c.CredentialSource.IMDSv2SessionTokenURL |
||||
} |
||||
|
||||
return awsCredSource, nil |
||||
} |
||||
} else if c.CredentialSource.File != "" { |
||||
return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format}, nil |
||||
} else if c.CredentialSource.URL != "" { |
||||
return urlCredentialSource{URL: c.CredentialSource.URL, Headers: c.CredentialSource.Headers, Format: c.CredentialSource.Format, ctx: ctx}, nil |
||||
} else if c.CredentialSource.Executable != nil { |
||||
return createExecutableCredential(ctx, c.CredentialSource.Executable, c) |
||||
} |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: unable to parse credential source") |
||||
} |
||||
|
||||
type baseCredentialSource interface { |
||||
credentialSourceType() string |
||||
subjectToken() (string, error) |
||||
} |
||||
|
||||
// tokenSource is the source that handles external credentials. It is used to retrieve Tokens.
|
||||
type tokenSource struct { |
||||
ctx context.Context |
||||
conf *Config |
||||
} |
||||
|
||||
func getMetricsHeaderValue(conf *Config, credSource baseCredentialSource) string { |
||||
return fmt.Sprintf("gl-go/%s auth/%s google-byoid-sdk source/%s sa-impersonation/%t config-lifetime/%t", |
||||
goVersion(), |
||||
"unknown", |
||||
credSource.credentialSourceType(), |
||||
conf.ServiceAccountImpersonationURL != "", |
||||
conf.ServiceAccountImpersonationLifetimeSeconds != 0) |
||||
} |
||||
|
||||
// Token allows tokenSource to conform to the oauth2.TokenSource interface.
|
||||
func (ts tokenSource) Token() (*oauth2.Token, error) { |
||||
conf := ts.conf |
||||
|
||||
credSource, err := conf.parse(ts.ctx) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
subjectToken, err := credSource.subjectToken() |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
stsRequest := stsexchange.TokenExchangeRequest{ |
||||
GrantType: "urn:ietf:params:oauth:grant-type:token-exchange", |
||||
Audience: conf.Audience, |
||||
Scope: conf.Scopes, |
||||
RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token", |
||||
SubjectToken: subjectToken, |
||||
SubjectTokenType: conf.SubjectTokenType, |
||||
} |
||||
header := make(http.Header) |
||||
header.Add("Content-Type", "application/x-www-form-urlencoded") |
||||
header.Add("x-goog-api-client", getMetricsHeaderValue(conf, credSource)) |
||||
clientAuth := stsexchange.ClientAuthentication{ |
||||
AuthStyle: oauth2.AuthStyleInHeader, |
||||
ClientID: conf.ClientID, |
||||
ClientSecret: conf.ClientSecret, |
||||
} |
||||
var options map[string]interface{} |
||||
// Do not pass workforce_pool_user_project when client authentication is used.
|
||||
// The client ID is sufficient for determining the user project.
|
||||
if conf.WorkforcePoolUserProject != "" && conf.ClientID == "" { |
||||
options = map[string]interface{}{ |
||||
"userProject": conf.WorkforcePoolUserProject, |
||||
} |
||||
} |
||||
stsResp, err := stsexchange.ExchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, options) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
accessToken := &oauth2.Token{ |
||||
AccessToken: stsResp.AccessToken, |
||||
TokenType: stsResp.TokenType, |
||||
} |
||||
|
||||
// The RFC8693 doesn't define the explicit 0 of "expires_in" field behavior.
|
||||
if stsResp.ExpiresIn <= 0 { |
||||
return nil, fmt.Errorf("oauth2/google/externalaccount: got invalid expiry from security token service") |
||||
} |
||||
accessToken.Expiry = now().Add(time.Duration(stsResp.ExpiresIn) * time.Second) |
||||
|
||||
if stsResp.RefreshToken != "" { |
||||
accessToken.RefreshToken = stsResp.RefreshToken |
||||
} |
||||
return accessToken, nil |
||||
} |
@ -0,0 +1,64 @@ |
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package externalaccount |
||||
|
||||
import ( |
||||
"runtime" |
||||
"strings" |
||||
"unicode" |
||||
) |
||||
|
||||
var ( |
||||
// version is a package internal global variable for testing purposes.
|
||||
version = runtime.Version |
||||
) |
||||
|
||||
// versionUnknown is only used when the runtime version cannot be determined.
|
||||
const versionUnknown = "UNKNOWN" |
||||
|
||||
// goVersion returns a Go runtime version derived from the runtime environment
|
||||
// that is modified to be suitable for reporting in a header, meaning it has no
|
||||
// whitespace. If it is unable to determine the Go runtime version, it returns
|
||||
// versionUnknown.
|
||||
func goVersion() string { |
||||
const develPrefix = "devel +" |
||||
|
||||
s := version() |
||||
if strings.HasPrefix(s, develPrefix) { |
||||
s = s[len(develPrefix):] |
||||
if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { |
||||
s = s[:p] |
||||
} |
||||
return s |
||||
} else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { |
||||
s = s[:p] |
||||
} |
||||
|
||||
notSemverRune := func(r rune) bool { |
||||
return !strings.ContainsRune("0123456789.", r) |
||||
} |
||||
|
||||
if strings.HasPrefix(s, "go1") { |
||||
s = s[2:] |
||||
var prerelease string |
||||
if p := strings.IndexFunc(s, notSemverRune); p >= 0 { |
||||
s, prerelease = s[:p], s[p:] |
||||
} |
||||
if strings.HasSuffix(s, ".") { |
||||
s += "0" |
||||
} else if strings.Count(s, ".") < 2 { |
||||
s += ".0" |
||||
} |
||||
if prerelease != "" { |
||||
// Some release candidates already have a dash in them.
|
||||
if !strings.HasPrefix(prerelease, "-") { |
||||
prerelease = "-" + prerelease |
||||
} |
||||
s += prerelease |
||||
} |
||||
return s |
||||
} |
||||
return "UNKNOWN" |
||||
} |
21
vendor/golang.org/x/oauth2/google/externalaccount/programmaticrefreshcredsource.go
generated
vendored
21
vendor/golang.org/x/oauth2/google/externalaccount/programmaticrefreshcredsource.go
generated
vendored
@ -0,0 +1,21 @@ |
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package externalaccount |
||||
|
||||
import "context" |
||||
|
||||
type programmaticRefreshCredentialSource struct { |
||||
supplierOptions SupplierOptions |
||||
subjectTokenSupplier SubjectTokenSupplier |
||||
ctx context.Context |
||||
} |
||||
|
||||
func (cs programmaticRefreshCredentialSource) credentialSourceType() string { |
||||
return "programmatic" |
||||
} |
||||
|
||||
func (cs programmaticRefreshCredentialSource) subjectToken() (string, error) { |
||||
return cs.subjectTokenSupplier.SubjectToken(cs.ctx, cs.supplierOptions) |
||||
} |
269
vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
generated
vendored
269
vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
generated
vendored
@ -1,269 +0,0 @@ |
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package externalaccount |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"net/http" |
||||
"net/url" |
||||
"regexp" |
||||
"strconv" |
||||
"strings" |
||||
"time" |
||||
|
||||
"golang.org/x/oauth2" |
||||
) |
||||
|
||||
// now aliases time.Now for testing
|
||||
var now = func() time.Time { |
||||
return time.Now().UTC() |
||||
} |
||||
|
||||
// Config stores the configuration for fetching tokens with external credentials.
|
||||
type Config struct { |
||||
// Audience is the Secure Token Service (STS) audience which contains the resource name for the workload
|
||||
// identity pool or the workforce pool and the provider identifier in that pool.
|
||||
Audience string |
||||
// SubjectTokenType is the STS token type based on the Oauth2.0 token exchange spec
|
||||
// e.g. `urn:ietf:params:oauth:token-type:jwt`.
|
||||
SubjectTokenType string |
||||
// TokenURL is the STS token exchange endpoint.
|
||||
TokenURL string |
||||
// TokenInfoURL is the token_info endpoint used to retrieve the account related information (
|
||||
// user attributes like account identifier, eg. email, username, uid, etc). This is
|
||||
// needed for gCloud session account identification.
|
||||
TokenInfoURL string |
||||
// ServiceAccountImpersonationURL is the URL for the service account impersonation request. This is only
|
||||
// required for workload identity pools when APIs to be accessed have not integrated with UberMint.
|
||||
ServiceAccountImpersonationURL string |
||||
// ServiceAccountImpersonationLifetimeSeconds is the number of seconds the service account impersonation
|
||||
// token will be valid for.
|
||||
ServiceAccountImpersonationLifetimeSeconds int |
||||
// ClientSecret is currently only required if token_info endpoint also
|
||||
// needs to be called with the generated GCP access token. When provided, STS will be
|
||||
// called with additional basic authentication using client_id as username and client_secret as password.
|
||||
ClientSecret string |
||||
// ClientID is only required in conjunction with ClientSecret, as described above.
|
||||
ClientID string |
||||
// CredentialSource contains the necessary information to retrieve the token itself, as well
|
||||
// as some environmental information.
|
||||
CredentialSource CredentialSource |
||||
// QuotaProjectID is injected by gCloud. If the value is non-empty, the Auth libraries
|
||||
// will set the x-goog-user-project which overrides the project associated with the credentials.
|
||||
QuotaProjectID string |
||||
// Scopes contains the desired scopes for the returned access token.
|
||||
Scopes []string |
||||
// The optional workforce pool user project number when the credential
|
||||
// corresponds to a workforce pool and not a workload identity pool.
|
||||
// The underlying principal must still have serviceusage.services.use IAM
|
||||
// permission to use the project for billing/quota.
|
||||
WorkforcePoolUserProject string |
||||
} |
||||
|
||||
// Each element consists of a list of patterns. validateURLs checks for matches
|
||||
// that include all elements in a given list, in that order.
|
||||
|
||||
var ( |
||||
validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`) |
||||
) |
||||
|
||||
func validateURL(input string, patterns []*regexp.Regexp, scheme string) bool { |
||||
parsed, err := url.Parse(input) |
||||
if err != nil { |
||||
return false |
||||
} |
||||
if !strings.EqualFold(parsed.Scheme, scheme) { |
||||
return false |
||||
} |
||||
toTest := parsed.Host |
||||
|
||||
for _, pattern := range patterns { |
||||
if pattern.MatchString(toTest) { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func validateWorkforceAudience(input string) bool { |
||||
return validWorkforceAudiencePattern.MatchString(input) |
||||
} |
||||
|
||||
// TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials.
|
||||
func (c *Config) TokenSource(ctx context.Context) (oauth2.TokenSource, error) { |
||||
return c.tokenSource(ctx, "https") |
||||
} |
||||
|
||||
// tokenSource is a private function that's directly called by some of the tests,
|
||||
// because the unit test URLs are mocked, and would otherwise fail the
|
||||
// validity check.
|
||||
func (c *Config) tokenSource(ctx context.Context, scheme string) (oauth2.TokenSource, error) { |
||||
if c.WorkforcePoolUserProject != "" { |
||||
valid := validateWorkforceAudience(c.Audience) |
||||
if !valid { |
||||
return nil, fmt.Errorf("oauth2/google: workforce_pool_user_project should not be set for non-workforce pool credentials") |
||||
} |
||||
} |
||||
|
||||
ts := tokenSource{ |
||||
ctx: ctx, |
||||
conf: c, |
||||
} |
||||
if c.ServiceAccountImpersonationURL == "" { |
||||
return oauth2.ReuseTokenSource(nil, ts), nil |
||||
} |
||||
scopes := c.Scopes |
||||
ts.conf.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"} |
||||
imp := ImpersonateTokenSource{ |
||||
Ctx: ctx, |
||||
URL: c.ServiceAccountImpersonationURL, |
||||
Scopes: scopes, |
||||
Ts: oauth2.ReuseTokenSource(nil, ts), |
||||
TokenLifetimeSeconds: c.ServiceAccountImpersonationLifetimeSeconds, |
||||
} |
||||
return oauth2.ReuseTokenSource(nil, imp), nil |
||||
} |
||||
|
||||
// Subject token file types.
|
||||
const ( |
||||
fileTypeText = "text" |
||||
fileTypeJSON = "json" |
||||
) |
||||
|
||||
type format struct { |
||||
// Type is either "text" or "json". When not provided "text" type is assumed.
|
||||
Type string `json:"type"` |
||||
// SubjectTokenFieldName is only required for JSON format. This would be "access_token" for azure.
|
||||
SubjectTokenFieldName string `json:"subject_token_field_name"` |
||||
} |
||||
|
||||
// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange.
|
||||
// One field amongst File, URL, and Executable should be filled, depending on the kind of credential in question.
|
||||
// The EnvironmentID should start with AWS if being used for an AWS credential.
|
||||
type CredentialSource struct { |
||||
File string `json:"file"` |
||||
|
||||
URL string `json:"url"` |
||||
Headers map[string]string `json:"headers"` |
||||
|
||||
Executable *ExecutableConfig `json:"executable"` |
||||
|
||||
EnvironmentID string `json:"environment_id"` |
||||
RegionURL string `json:"region_url"` |
||||
RegionalCredVerificationURL string `json:"regional_cred_verification_url"` |
||||
CredVerificationURL string `json:"cred_verification_url"` |
||||
IMDSv2SessionTokenURL string `json:"imdsv2_session_token_url"` |
||||
Format format `json:"format"` |
||||
} |
||||
|
||||
type ExecutableConfig struct { |
||||
Command string `json:"command"` |
||||
TimeoutMillis *int `json:"timeout_millis"` |
||||
OutputFile string `json:"output_file"` |
||||
} |
||||
|
||||
// parse determines the type of CredentialSource needed.
|
||||
func (c *Config) parse(ctx context.Context) (baseCredentialSource, error) { |
||||
if len(c.CredentialSource.EnvironmentID) > 3 && c.CredentialSource.EnvironmentID[:3] == "aws" { |
||||
if awsVersion, err := strconv.Atoi(c.CredentialSource.EnvironmentID[3:]); err == nil { |
||||
if awsVersion != 1 { |
||||
return nil, fmt.Errorf("oauth2/google: aws version '%d' is not supported in the current build", awsVersion) |
||||
} |
||||
|
||||
awsCredSource := awsCredentialSource{ |
||||
EnvironmentID: c.CredentialSource.EnvironmentID, |
||||
RegionURL: c.CredentialSource.RegionURL, |
||||
RegionalCredVerificationURL: c.CredentialSource.RegionalCredVerificationURL, |
||||
CredVerificationURL: c.CredentialSource.URL, |
||||
TargetResource: c.Audience, |
||||
ctx: ctx, |
||||
} |
||||
if c.CredentialSource.IMDSv2SessionTokenURL != "" { |
||||
awsCredSource.IMDSv2SessionTokenURL = c.CredentialSource.IMDSv2SessionTokenURL |
||||
} |
||||
|
||||
if err := awsCredSource.validateMetadataServers(); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
return awsCredSource, nil |
||||
} |
||||
} else if c.CredentialSource.File != "" { |
||||
return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format}, nil |
||||
} else if c.CredentialSource.URL != "" { |
||||
return urlCredentialSource{URL: c.CredentialSource.URL, Headers: c.CredentialSource.Headers, Format: c.CredentialSource.Format, ctx: ctx}, nil |
||||
} else if c.CredentialSource.Executable != nil { |
||||
return CreateExecutableCredential(ctx, c.CredentialSource.Executable, c) |
||||
} |
||||
return nil, fmt.Errorf("oauth2/google: unable to parse credential source") |
||||
} |
||||
|
||||
type baseCredentialSource interface { |
||||
subjectToken() (string, error) |
||||
} |
||||
|
||||
// tokenSource is the source that handles external credentials. It is used to retrieve Tokens.
|
||||
type tokenSource struct { |
||||
ctx context.Context |
||||
conf *Config |
||||
} |
||||
|
||||
// Token allows tokenSource to conform to the oauth2.TokenSource interface.
|
||||
func (ts tokenSource) Token() (*oauth2.Token, error) { |
||||
conf := ts.conf |
||||
|
||||
credSource, err := conf.parse(ts.ctx) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
subjectToken, err := credSource.subjectToken() |
||||
|
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
stsRequest := stsTokenExchangeRequest{ |
||||
GrantType: "urn:ietf:params:oauth:grant-type:token-exchange", |
||||
Audience: conf.Audience, |
||||
Scope: conf.Scopes, |
||||
RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token", |
||||
SubjectToken: subjectToken, |
||||
SubjectTokenType: conf.SubjectTokenType, |
||||
} |
||||
header := make(http.Header) |
||||
header.Add("Content-Type", "application/x-www-form-urlencoded") |
||||
clientAuth := clientAuthentication{ |
||||
AuthStyle: oauth2.AuthStyleInHeader, |
||||
ClientID: conf.ClientID, |
||||
ClientSecret: conf.ClientSecret, |
||||
} |
||||
var options map[string]interface{} |
||||
// Do not pass workforce_pool_user_project when client authentication is used.
|
||||
// The client ID is sufficient for determining the user project.
|
||||
if conf.WorkforcePoolUserProject != "" && conf.ClientID == "" { |
||||
options = map[string]interface{}{ |
||||
"userProject": conf.WorkforcePoolUserProject, |
||||
} |
||||
} |
||||
stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, options) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
accessToken := &oauth2.Token{ |
||||
AccessToken: stsResp.AccessToken, |
||||
TokenType: stsResp.TokenType, |
||||
} |
||||
if stsResp.ExpiresIn < 0 { |
||||
return nil, fmt.Errorf("oauth2/google: got invalid expiry from security token service") |
||||
} else if stsResp.ExpiresIn >= 0 { |
||||
accessToken.Expiry = now().Add(time.Duration(stsResp.ExpiresIn) * time.Second) |
||||
} |
||||
|
||||
if stsResp.RefreshToken != "" { |
||||
accessToken.RefreshToken = stsResp.RefreshToken |
||||
} |
||||
return accessToken, nil |
||||
} |
@ -1,18 +0,0 @@ |
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package externalaccount |
||||
|
||||
import "fmt" |
||||
|
||||
// Error for handling OAuth related error responses as stated in rfc6749#5.2.
|
||||
type Error struct { |
||||
Code string |
||||
URI string |
||||
Description string |
||||
} |
||||
|
||||
func (err *Error) Error() string { |
||||
return fmt.Sprintf("got error code %s from %s: %s", err.Code, err.URI, err.Description) |
||||
} |
@ -0,0 +1,114 @@ |
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package externalaccountauthorizeduser |
||||
|
||||
import ( |
||||
"context" |
||||
"errors" |
||||
"time" |
||||
|
||||
"golang.org/x/oauth2" |
||||
"golang.org/x/oauth2/google/internal/stsexchange" |
||||
) |
||||
|
||||
// now aliases time.Now for testing.
|
||||
var now = func() time.Time { |
||||
return time.Now().UTC() |
||||
} |
||||
|
||||
var tokenValid = func(token oauth2.Token) bool { |
||||
return token.Valid() |
||||
} |
||||
|
||||
type Config struct { |
||||
// Audience is the Secure Token Service (STS) audience which contains the resource name for the workforce pool and
|
||||
// the provider identifier in that pool.
|
||||
Audience string |
||||
// RefreshToken is the optional OAuth 2.0 refresh token. If specified, credentials can be refreshed.
|
||||
RefreshToken string |
||||
// TokenURL is the optional STS token exchange endpoint for refresh. Must be specified for refresh, can be left as
|
||||
// None if the token can not be refreshed.
|
||||
TokenURL string |
||||
// TokenInfoURL is the optional STS endpoint URL for token introspection.
|
||||
TokenInfoURL string |
||||
// ClientID is only required in conjunction with ClientSecret, as described above.
|
||||
ClientID string |
||||
// ClientSecret is currently only required if token_info endpoint also needs to be called with the generated GCP
|
||||
// access token. When provided, STS will be called with additional basic authentication using client_id as username
|
||||
// and client_secret as password.
|
||||
ClientSecret string |
||||
// Token is the OAuth2.0 access token. Can be nil if refresh information is provided.
|
||||
Token string |
||||
// Expiry is the optional expiration datetime of the OAuth 2.0 access token.
|
||||
Expiry time.Time |
||||
// RevokeURL is the optional STS endpoint URL for revoking tokens.
|
||||
RevokeURL string |
||||
// QuotaProjectID is the optional project ID used for quota and billing. This project may be different from the
|
||||
// project used to create the credentials.
|
||||
QuotaProjectID string |
||||
Scopes []string |
||||
} |
||||
|
||||
func (c *Config) canRefresh() bool { |
||||
return c.ClientID != "" && c.ClientSecret != "" && c.RefreshToken != "" && c.TokenURL != "" |
||||
} |
||||
|
||||
func (c *Config) TokenSource(ctx context.Context) (oauth2.TokenSource, error) { |
||||
var token oauth2.Token |
||||
if c.Token != "" && !c.Expiry.IsZero() { |
||||
token = oauth2.Token{ |
||||
AccessToken: c.Token, |
||||
Expiry: c.Expiry, |
||||
TokenType: "Bearer", |
||||
} |
||||
} |
||||
if !tokenValid(token) && !c.canRefresh() { |
||||
return nil, errors.New("oauth2/google: Token should be created with fields to make it valid (`token` and `expiry`), or fields to allow it to refresh (`refresh_token`, `token_url`, `client_id`, `client_secret`).") |
||||
} |
||||
|
||||
ts := tokenSource{ |
||||
ctx: ctx, |
||||
conf: c, |
||||
} |
||||
|
||||
return oauth2.ReuseTokenSource(&token, ts), nil |
||||
} |
||||
|
||||
type tokenSource struct { |
||||
ctx context.Context |
||||
conf *Config |
||||
} |
||||
|
||||
func (ts tokenSource) Token() (*oauth2.Token, error) { |
||||
conf := ts.conf |
||||
if !conf.canRefresh() { |
||||
return nil, errors.New("oauth2/google: The credentials do not contain the necessary fields need to refresh the access token. You must specify refresh_token, token_url, client_id, and client_secret.") |
||||
} |
||||
|
||||
clientAuth := stsexchange.ClientAuthentication{ |
||||
AuthStyle: oauth2.AuthStyleInHeader, |
||||
ClientID: conf.ClientID, |
||||
ClientSecret: conf.ClientSecret, |
||||
} |
||||
|
||||
stsResponse, err := stsexchange.RefreshAccessToken(ts.ctx, conf.TokenURL, conf.RefreshToken, clientAuth, nil) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
if stsResponse.ExpiresIn < 0 { |
||||
return nil, errors.New("oauth2/google: got invalid expiry from security token service") |
||||
} |
||||
|
||||
if stsResponse.RefreshToken != "" { |
||||
conf.RefreshToken = stsResponse.RefreshToken |
||||
} |
||||
|
||||
token := &oauth2.Token{ |
||||
AccessToken: stsResponse.AccessToken, |
||||
Expiry: now().Add(time.Duration(stsResponse.ExpiresIn) * time.Second), |
||||
TokenType: "Bearer", |
||||
} |
||||
return token, nil |
||||
} |
@ -1,14 +0,0 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
package internal |
||||
|
||||
import "google.golang.org/appengine/urlfetch" |
||||
|
||||
func init() { |
||||
appengineClientHook = urlfetch.Client |
||||
} |
@ -0,0 +1,68 @@ |
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
package oauth2 |
||||
|
||||
import ( |
||||
"crypto/rand" |
||||
"crypto/sha256" |
||||
"encoding/base64" |
||||
"net/url" |
||||
) |
||||
|
||||
const ( |
||||
codeChallengeKey = "code_challenge" |
||||
codeChallengeMethodKey = "code_challenge_method" |
||||
codeVerifierKey = "code_verifier" |
||||
) |
||||
|
||||
// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness.
|
||||
// This follows recommendations in RFC 7636.
|
||||
//
|
||||
// A fresh verifier should be generated for each authorization.
|
||||
// S256ChallengeOption(verifier) should then be passed to Config.AuthCodeURL
|
||||
// (or Config.DeviceAuth) and VerifierOption(verifier) to Config.Exchange
|
||||
// (or Config.DeviceAccessToken).
|
||||
func GenerateVerifier() string { |
||||
// "RECOMMENDED that the output of a suitable random number generator be
|
||||
// used to create a 32-octet sequence. The octet sequence is then
|
||||
// base64url-encoded to produce a 43-octet URL-safe string to use as the
|
||||
// code verifier."
|
||||
// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
||||
data := make([]byte, 32) |
||||
if _, err := rand.Read(data); err != nil { |
||||
panic(err) |
||||
} |
||||
return base64.RawURLEncoding.EncodeToString(data) |
||||
} |
||||
|
||||
// VerifierOption returns a PKCE code verifier AuthCodeOption. It should be
|
||||
// passed to Config.Exchange or Config.DeviceAccessToken only.
|
||||
func VerifierOption(verifier string) AuthCodeOption { |
||||
return setParam{k: codeVerifierKey, v: verifier} |
||||
} |
||||
|
||||
// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.
|
||||
//
|
||||
// Prefer to use S256ChallengeOption where possible.
|
||||
func S256ChallengeFromVerifier(verifier string) string { |
||||
sha := sha256.Sum256([]byte(verifier)) |
||||
return base64.RawURLEncoding.EncodeToString(sha[:]) |
||||
} |
||||
|
||||
// S256ChallengeOption derives a PKCE code challenge derived from verifier with
|
||||
// method S256. It should be passed to Config.AuthCodeURL or Config.DeviceAuth
|
||||
// only.
|
||||
func S256ChallengeOption(verifier string) AuthCodeOption { |
||||
return challengeOption{ |
||||
challenge_method: "S256", |
||||
challenge: S256ChallengeFromVerifier(verifier), |
||||
} |
||||
} |
||||
|
||||
type challengeOption struct{ challenge_method, challenge string } |
||||
|
||||
func (p challengeOption) setValue(m url.Values) { |
||||
m.Set(codeChallengeMethodKey, p.challenge_method) |
||||
m.Set(codeChallengeKey, p.challenge) |
||||
} |
Loading…
Reference in new issue