Compare commits

...

12 Commits

Author SHA1 Message Date
Gopher Robot
8a4c24f9bb [release-branch.go1.24] go1.24rc2
Change-Id: I37362fe37c47078c17f3f6f610d8ca7664985bd0
Reviewed-on: https://go-review.googlesource.com/c/go/+/643157
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2025-01-16 12:13:48 -08:00
Filippo Valsorda
3de5aca7d0 [release-branch.go1.24] crypto/x509: avoid panic when parsing partial PKCS#1 private keys
These keys are off-spec, but have historically been accepted by
ParsePKCS1PrivateKey.

Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

Fixes #71216
Fixes CVE-2025-22865

Change-Id: I6a6a46564156fa32e29e8d6acbec3fbac47c7352
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1820
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit 36c6c8b6957e155770461fd710aea9477ef3bc88)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1841
Reviewed-on: https://go-review.googlesource.com/c/go/+/643102
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-01-16 11:36:09 -08:00
Sam Thanawalla
8336dfde70 [release-branch.go1.24] cmd/go: restore netrc preferences for GOAUTH and fix domain lookup
Store netrc lines into the credential map backward so that earlier lines
take priority over later lines. This matches Go 1.23 netrc lookup which
stopped at the first match it found.
Additionally, this fixes a security issue related to domain parsing
which could have allowed servers to read credentials belonging to other
servers. The fix was to switch from using path.Dir(currentPrefix) to
strings.Cut(currentPrefix, "/")

Thanks to Juho Forsén of Mattermost for reporting this issue.

Fixes #71249
Fixes CVE-2024-45340

Change-Id: I175a00d6d7f4d31c9e4d79b7cf1c2a0ad35b2781
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1781
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 76833d221aa3ccc978b6f41bd24e26babf771375)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1840
Reviewed-on: https://go-review.googlesource.com/c/go/+/643101
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-16 11:36:07 -08:00
Damien Neil
6b60550504 [release-branch.go1.24] net/http: persist header stripping across repeated redirects
When an HTTP redirect changes the host of a request, we drop
sensitive headers such as Authorization from the redirected request.
Fix a bug where a chain of redirects could result in sensitive
headers being sent to the wrong host:

  1. request to a.tld with Authorization header
  2. a.tld redirects to b.tld
  3. request to b.tld with no Authorization header
  4. b.tld redirects to b.tld
  3. request to b.tld with Authorization header restored

Thanks to Kyle Seely for reporting this issue.

For #70530
Fixes #71212
Fixes CVE-2024-45336

Change-Id: Ia58a2e10d33d6b0cc7220935e771450e5c34de72
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1641
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit 2889169b87a61f1218a02994feb80fd3d8bfa87c)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1766
Reviewed-on: https://go-review.googlesource.com/c/go/+/643100
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-01-16 11:36:03 -08:00
Roland Shoemaker
468fad45a2 [release-branch.go1.24] crypto/x509: properly check for IPv6 hosts in URIs
When checking URI constraints, use netip.ParseAddr, which understands
zones, unlike net.ParseIP which chokes on them. This prevents zone IDs
from mistakenly satisfying URI constraints.

Thanks to Juho Forsén of Mattermost for reporting this issue.

For #71156
Fixes #71209
Fixes CVE-2024-45341

Change-Id: Iecac2529f3605382d257996e0fb6d6983547e400
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1700
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 22ca55d396ba801e6ae9b2bd67a059fcb30562fd)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1800
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/643099
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-01-16 11:08:59 -08:00
Michael Pratt
e06b6fc58d [release-branch.go1.24] all: merge master (e966a27) into release-branch.go1.24
Merge List:

+ 2025-01-08 e966a2773c crypto/internal/fips140/drbg: avoid global lock on rand state

Change-Id: I1ca8f6bf2ba14ff3d5c4183a26cbd51ac20dad0a
2025-01-08 14:01:58 -05:00
Michael Pratt
b3799ba634 [release-branch.go1.24] all: merge master (9a44df6) into release-branch.go1.24
Merge List:

+ 2025-01-08 9a44df6675 cmd/go/testdata/script: fix TestScript/env_gocacheprog on Windows
+ 2025-01-08 f025d19e7b runtime: hold traceAcquire across casgstatus in injectglist
+ 2025-01-08 1e9835f5b1 internal/sync: fix typo of panic message
+ 2025-01-07 39f2032c17 testing/synctest: add some examples
+ 2025-01-07 b50ccef67a cmd/go/internal/modindex: don't write index entry if file open
+ 2025-01-07 b2aa18b96c cmd/internal/hash: stop using md5, sha1
+ 2025-01-07 d93b549f05 cmd/go/internal/cache: handle cacheprog not responding to close
+ 2025-01-07 d62154db83 weak: don't panic when calling Value on a zero Pointer
+ 2025-01-07 9d0772b23e cmd/compile/internal/syntax: add test case for invalid label use
+ 2025-01-07 1d20bce981 go/types, types2: expand documentation for Info.Types map
+ 2025-01-07 a9bd6239a4 cmd/go/internal/env: add GOCACHEPROG to go env output
+ 2025-01-07 850b276a67 crypto/tls: send illegal_parameter on invalid ECHClientHello.type
+ 2025-01-06 27c5164374 crypto/internal/fips140: zeroise integrity test temporary values
+ 2025-01-06 d8ad4af78b cmd/internal/disasm: correct instruction length handling for riscv64
+ 2025-01-06 a76cc5a4ec crypto/rsa: use λ(N) instead of φ(N)
+ 2025-01-06 3f002abb60 internal/sync: add test from issue 70970
+ 2025-01-06 7a2e88e911 net/http: update NewRequestWithContext wrong link to NewRequest
+ 2025-01-06 c112c0af13 Revert "internal/sync: optimize CompareAndSwap and Swap"
+ 2025-01-03 705b5a569a crypto/ecdsa: drop SEC 1 reference from package doc
+ 2025-01-03 f966695cce context: use "canceled" in docs to refer to timed-out contexts
+ 2025-01-03 5da026354c cmd/go/internal/vcweb: close the .access file
+ 2025-01-03 31cabcf084 crypto/internal/fips140: mark OpenBSD unsupported
+ 2025-01-03 eb0c2b2f96 crypto/internal/fips140: add Supported
+ 2025-01-03 f0a9b6df45 internal/fuzz: remove the exp2 method
+ 2025-01-03 5d626c49ec spec: fix a dead link
+ 2025-01-03 81566aff3a internal/exportdata: add missing return
+ 2025-01-03 e7a8bd5d8b crypto/internal/fips140/check: remove Enabled
+ 2025-01-02 4b652e9f5f cmd/go: fix two typos in helpdoc.go
+ 2025-01-02 0afd7e85e5 cmd/go: document GOCACHEPROG in go help environment
+ 2025-01-02 3c8e5b13df cmd/go/internal/cacheprog: drop redundant Prog prefixes
+ 2025-01-02 20da34c6d2 cmd/go: move GOCACHEPROG protocol types to their own package
+ 2025-01-02 858a0e9dfd crypto/tls: properly return ECH retry configs
+ 2025-01-02 a63aee4955 cmd/go: improve GOCACHEPROG types documentation
+ 2025-01-02 847c357bbb cmd/go: remove references to gopath-get
+ 2025-01-01 d1d9312950 crypto/tls: fix Config.Time in tests using expired certificates
+ 2024-12-31 94f15810e6 cmd/go: document default GOARM value
+ 2024-12-30 856a7bc8e9 builtin: use list instead of indentation for comments in cap, len, and make
+ 2024-12-30 5efb4239c6 spec: document that string conversions don't guarantee result slice capacity
+ 2024-12-30 0d8aa8cce6 spec: describe representation of values
+ 2024-12-30 8857a5a33f crypto/tls: fix misspelling in comment
+ 2024-12-30 3c4102bfd4 encoding/binary: add documentation for endian methods
+ 2024-12-30 b702a26cf8 os: mention fsys modifications during CopyFS
+ 2024-12-30 15f232456a encoding/json: remove suggestion on Unmarshaler with JSON null
+ 2024-12-30 ba1deb1cee cmd/link: document that -s implies -w
+ 2024-12-30 fd5e0d26d9 go/doc: resolve imports before predeclared identifiers in examples
+ 2024-12-30 a785d11ac4 unique: fix typo
+ 2024-12-27 2b794ed86c encoding/json: expand and modernize TestInterfaceSet
+ 2024-12-27 e3cd55e9d2 cmd/go/internal/work: allow @ character in some -Wl, linker flags on darwin
+ 2024-12-27 39794819aa doc/initial: remove fixed-width spacing notice
+ 2024-12-27 7c03fe70b8 cmd/compile: improve compiler directive docs
+ 2024-12-27 d7c3e93c16 iter: improve documentation with iterator example
+ 2024-12-26 cce75da30b crypto/mlkem: swap order of return values of Encapsulate
+ 2024-12-23 772f024c61 weak: fix typo in warning about tiny allocator optimization
+ 2024-12-23 b9955f0ad9 cmd/link, runtime: apply a delta to RODATA->DATA relocations
+ 2024-12-23 eef35e3bd9 internal/goexperiment: run go generate for synctest
+ 2024-12-23 9f6c80a76a cmd/go/internal/work: allow single character values in -Wl, linker flags
+ 2024-12-22 05d8984781 net: document LookupTXT behavior with multiple strings per record
+ 2024-12-21 500675a7c8 cmd/compile: load map length with the right type
+ 2024-12-21 06b191e11f internal/syscall/unix: apply fstatat fix to linux/mips64le
+ 2024-12-21 110ab1aaf4 slices: document two oddities
+ 2024-12-19 669d87a935 runtime/pprof: continued attempt to deflake the VMInfo test.
+ 2024-12-19 45f49139f5 runtime: test trap panic parsing in TestTracebackSystem
+ 2024-12-19 e63eb98e98 net/http: fix nil panic in test
+ 2024-12-19 7b6c94dd03 cmd/go: drop fips140 build ID hacks
+ 2024-12-19 cb72406c36 cmd/go: fix two-step toolchain upgrade through go install, GOTOOLCHAIN
+ 2024-12-18 4f0561f9d3 cmd/dist: skip fips140test in exe mode on Android
+ 2024-12-18 87dbfb9fa7 weak: improve grammar in doc comments
+ 2024-12-18 f4e3ec3dbe crypto/ecdsa: fix condition for fips140=only check
+ 2024-12-18 6aa46eb750 crypto/tls: normalize spelling of "ClientHello" in comments
+ 2024-12-18 10ca5ba4ff crypto/pbkdf2: update RFC reference in package doc
+ 2024-12-18 8ff4cee564 cmd/go,crypto: reject using Go+BoringCrypto and fips140 together
+ 2024-12-18 971448ddf8 testing: support B.Context and F.Context
+ 2024-12-17 95b433eed4 debug/elf: adjust version API per issue discussion
+ 2024-12-17 b2c0168893 crypto/internal/fips140/aes/gcm: use aes.EncryptBlockInternal on ppc64x and s390x
+ 2024-12-17 b9e2ffdcd2 crypto/internal/fips140: add Name and Version
+ 2024-12-17 8790372a8d cmd, go: fix some typos
+ 2024-12-17 b057b8872d bytes, strings: add cross-references in docstrings
+ 2024-12-17 e977b83b32 cmd/go/internal/help: use secure link to swig.org
+ 2024-12-17 4ac8f552e9 syscall, internal/syscall/unix: fix fstatat on linux/mips64
+ 2024-12-17 236a0b4ffb spec: explain function invocation and passing of parameters more precisely
+ 2024-12-17 9f806bb76c go/build: streamline the crypto package graph in TestDependencies
+ 2024-12-17 0cd833d198 go/build: remove nonexistent package from TestDependencies
+ 2024-12-17 31e50af5f3 crypto/rsa: revert minimum GenerateKey size to 32 bits
+ 2024-12-17 b47ce8b0e9 crypto/cipher: block non-AES CTR and CBC in fips140=only mode
+ 2024-12-17 dd7a7ba38f crypto/internal/fips140/aes: mark AES-ECB as not approved
+ 2024-12-17 427a2401af cmd/go/testdata/script: update test_flags for new test output
+ 2024-12-17 75736cc169 fmt, strconv: document that exponent is always two digits
+ 2024-12-16 1218566fe5 cmd/link: update runtime dependency list
+ 2024-12-16 d92c34a387 cmd/go: don't create test actions for incomplete packages
+ 2024-12-16 3bd08b9792 runtime: usleep in TestWeakToStrongMarkTermination
+ 2024-12-15 18b5435fc8 testing: don't measure cleanup time after B.Loop
+ 2024-12-15 c1f2542c8b testing: improve B.Loop test
+ 2024-12-15 6bd56fcaeb testing: improve b.Loop example
+ 2024-12-15 090748d6c7 testing: improve B.Loop docs, use B.Loop in examples
+ 2024-12-13 e39e965e0e cmd/go: drop FailedBuild field if gotestjsonbuildtext=1
+ 2024-12-13 08770a5b94 cmd/link: make dwarf name slice index self-describing
+ 2024-12-13 c4f356dd86 crypto/ecdsa: fix s390x assembly with P-521
+ 2024-12-13 08725f9de2 crypto/internal/cryptotest: skip TestAllocations on s390x
+ 2024-12-13 1cbfe8c482 fmt: add more function and allocation tests
+ 2024-12-13 8391579ece runtime: migrate missing map linkname allowlists
+ 2024-12-12 80a2982a80 spec: align EBNF rules consistently (cosmetic change)
+ 2024-12-12 38e9a671d7 syscall: on freebsd-386 only update written for certain errors
+ 2024-12-12 6f7a4540b1 net: fix example function name for IP.To4
+ 2024-12-12 14e5093ee5 cmd/internal/obj: disallow linknamed access to builtin symbols
+ 2024-12-12 fb764cdad0 cmd/link: block new standard library linknames

Change-Id: Ie423f050db80034c3af6c12bd6007db273c5d281
2025-01-08 13:21:10 -05:00
Gopher Robot
16afa6a740 [release-branch.go1.24] go1.24rc1
Change-Id: Ia3b0a8ec25312b73879d2561a2b4d1cfc648c295
Reviewed-on: https://go-review.googlesource.com/c/go/+/636036
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
TryBot-Bypass: Carlos Amedee <carlos@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2024-12-13 08:52:10 -08:00
Carlos Amedee
817d7bdc0a [release-branch.go1.24] all: merge master (9118060) into release-branch.go1.24
Merge List:

+ 2024-12-12 9118060040 builtin: document clear is a no-op if its argument's value is nil
+ 2024-12-11 077d51909d internal/poll: in SendFile treat ENOTSUP like EOPNOTSUPP
+ 2024-12-11 fafd4477f3 cmd/cgo: use full prototype for main in C code

Change-Id: I4c4941eff4a1e842920eb9be47d28351af0e4c36
2024-12-12 12:06:37 -05:00
Carlos Amedee
14bb1e11b9 [release-branch.go1.24] all: merge master (0ca521f) into release-branch.go1.24
Merge List:

+ 2024-12-11 0ca521f9c1 debug/elf: adjust version API per issue discussion

Change-Id: Ibd6f628528dd366837ad0bbacad624474eee0088
2024-12-11 18:55:28 -05:00
Carlos Amedee
2297c34cdf [release-branch.go1.24] all: merge master (c93477b) into release-branch.go1.24
Merge List:

+ 2024-12-11 c93477b5e5 crypto: use provided random Reader in FIPS mode
+ 2024-12-11 3104b6adbb log/slog: make DiscardHandler example package-level
+ 2024-12-11 5424f2e200 cmd/go: add more tests for GOAUTH's user provided authenticator
+ 2024-12-11 d5c1333eb4 net/http: document zero value of Protocols
+ 2024-12-11 a7c4cadce0 cmd/compile: update broken link
+ 2024-12-11 979c1cfbe8 net: avoid unnecessary interface lookup fetching all interface addresses
+ 2024-12-11 e424d78c3d internal/goos: fix bug in gengoos.go
+ 2024-12-11 6c25cf1c5f cmd/internal/objfile: break out dissassemblers to another package
+ 2024-12-11 e0c76d95ab syscall: remove a wrong comment in Clearenv
+ 2024-12-11 a9922d096f reflect: consistently document when value must be settable
+ 2024-12-10 4ce116a884 runtime: avoid panic in expired synctest timer chan read
+ 2024-12-10 e6de1b2deb html/template: escape script tags in JS errors case insensitively
+ 2024-12-10 fce17b0c77 crypto/internal/fips140/ecdsa: fix reseed_counter check for HMAC_DRBG_Generate_algorithm
+ 2024-12-09 d87878c62b runtime: make special offset a uintptr
+ 2024-12-09 6705ac6885 runtime: remove datadog-agent from prof labels hall of shame
+ 2024-12-09 07398d2e57 weak: align weak.Pointer documentation with runtime.AddCleanup
+ 2024-12-09 e3e1d73528 bufio: make the description of Peek's behavior better
+ 2024-12-09 e79b2e1e3a cmd/go: document the build cache as safe for concurrent use
+ 2024-12-08 c8fb6ae617 lib/wasm: provide fs.constants.O_DIRECTORY definition
+ 2024-12-07 8c3e391573 runtime: improve AddCleanup documentation
+ 2024-12-07 04cdaa9984 cmd/go: document c-shared buildmode for building WASI library/reactor
+ 2024-12-06 312f7c1bd3 runtime: add note that Callers never returns an entry PC

Change-Id: I52e035228121de3d8219ab13f195d4293daaaa34
2024-12-11 17:45:39 -05:00
Michael Anthony Knyszek
26682773ca [release-branch.go1.24] update codereview.cfg for release-branch.go1.24
Change-Id: I63ffca43a935bc5ff060f19c01152a20182cba03
Reviewed-on: https://go-review.googlesource.com/c/go/+/634317
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2024-12-06 21:58:36 +00:00
12 changed files with 244 additions and 117 deletions

2
VERSION Normal file
View File

@ -0,0 +1,2 @@
go1.24rc2
time 2025-01-13T18:38:39Z

View File

@ -1 +1,2 @@
branch: master
branch: release-branch.go1.24
parent-branch: master

View File

@ -12,7 +12,6 @@ import (
"log"
"net/http"
"os"
"path"
"path/filepath"
"slices"
"strings"
@ -73,7 +72,12 @@ func runGoAuth(client *http.Client, res *http.Response, url string) {
if err != nil {
base.Fatalf("go: could not parse netrc (GOAUTH=%s): %v", cfg.GOAUTH, err)
}
for _, l := range lines {
// Process lines in reverse so that if the same machine is listed
// multiple times, we end up saving the earlier one
// (overwriting later ones). This matches the way the go command
// worked before GOAUTH.
for i := len(lines) - 1; i >= 0; i-- {
l := lines[i]
r := http.Request{Header: make(http.Header)}
r.SetBasicAuth(l.login, l.password)
storeCredential(l.machine, r.Header)
@ -137,11 +141,13 @@ func runGoAuth(client *http.Client, res *http.Response, url string) {
func loadCredential(req *http.Request, url string) bool {
currentPrefix := strings.TrimPrefix(url, "https://")
// Iteratively try prefixes, moving up the path hierarchy.
for currentPrefix != "/" && currentPrefix != "." && currentPrefix != "" {
for {
headers, ok := credentialCache.Load(currentPrefix)
if !ok {
// Move to the parent directory.
currentPrefix = path.Dir(currentPrefix)
currentPrefix, _, ok = strings.Cut(currentPrefix, "/")
if !ok {
return false
}
continue
}
for key, values := range headers.(http.Header) {
@ -151,7 +157,6 @@ func loadCredential(req *http.Request, url string) bool {
}
return true
}
return false
}
// storeCredential caches or removes credentials (represented by HTTP headers)

View File

@ -25,7 +25,29 @@ func TestCredentialCache(t *testing.T) {
got := &http.Request{Header: make(http.Header)}
ok := loadCredential(got, tc.machine)
if !ok || !reflect.DeepEqual(got.Header, want.Header) {
t.Errorf("loadCredential:\nhave %q\nwant %q", got.Header, want.Header)
t.Errorf("loadCredential(%q):\nhave %q\nwant %q", tc.machine, got.Header, want.Header)
}
}
// Having stored those credentials, we should be able to look up longer URLs too.
extraCases := []netrcLine{
{"https://api.github.com/foo", "user", "pwd"},
{"https://api.github.com/foo/bar/baz", "user", "pwd"},
{"https://example.com/abc", "", ""},
{"https://example.com/?/../api.github.com/", "", ""},
{"https://example.com/?/../api.github.com", "", ""},
{"https://example.com/../api.github.com/", "", ""},
{"https://example.com/../api.github.com", "", ""},
}
for _, tc := range extraCases {
want := http.Request{Header: make(http.Header)}
if tc.login != "" {
want.SetBasicAuth(tc.login, tc.password)
}
got := &http.Request{Header: make(http.Header)}
loadCredential(got, tc.machine)
if !reflect.DeepEqual(got.Header, want.Header) {
t.Errorf("loadCredential(%q):\nhave %q\nwant %q", tc.machine, got.Header, want.Header)
}
}
}

View File

@ -2,8 +2,6 @@
# credentials passed in HTTPS requests to VCS servers.
# See golang.org/issue/26232
[short] skip
env GOPROXY=direct
env GOSUMDB=off
@ -55,7 +53,6 @@ go get vcs-test.golang.org/auth/or401
env NETRC=$WORK/missing
! go get vcs-test.golang.org/auth/or401
stderr '^\tserver response: ACCESS DENIED, buddy$'
-- go.mod --
module private.example.com
-- $WORK/empty --
@ -63,3 +60,7 @@ module private.example.com
machine vcs-test.golang.org
login aladdin
password opensesame
# first one should override this one
machine vcs-test.golang.org
login aladdin
password ignored

View File

@ -1607,6 +1607,23 @@ var nameConstraintsTests = []nameConstraintsTest{
leaf: leafSpec{sans: []string{"dns:.example.com"}},
expectedError: "cannot parse dnsName \".example.com\"",
},
// #86: URIs with IPv6 addresses with zones and ports are rejected
{
roots: []constraintsSpec{
{
ok: []string{"uri:example.com"},
},
},
intermediates: [][]constraintsSpec{
{
{},
},
},
leaf: leafSpec{
sans: []string{"uri:http://[2006:abcd::1%25.example.com]:16/"},
},
expectedError: "URI with IP",
},
}
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {

View File

@ -72,7 +72,9 @@ func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
}
if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 ||
priv.Dp.Sign() <= 0 || priv.Dq.Sign() <= 0 || priv.Qinv.Sign() <= 0 {
priv.Dp != nil && priv.Dp.Sign() <= 0 ||
priv.Dq != nil && priv.Dq.Sign() <= 0 ||
priv.Qinv != nil && priv.Qinv.Sign() <= 0 {
return nil, errors.New("x509: private key contains zero or negative value")
}

View File

@ -13,6 +13,7 @@ import (
"iter"
"maps"
"net"
"net/netip"
"net/url"
"reflect"
"runtime"
@ -465,8 +466,10 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
}
}
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
net.ParseIP(host) != nil {
// netip.ParseAddr will reject the URI IPv6 literal form "[...]", so we
// check if _either_ the string parses as an IP, or if it is enclosed in
// square brackets.
if _, err := netip.ParseAddr(host); err == nil || (strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]")) {
return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
}

View File

@ -59,6 +59,32 @@ func TestParsePKCS1PrivateKey(t *testing.T) {
if _, err := ParsePKCS1PrivateKey(data); err == nil {
t.Errorf("parsing invalid private key did not result in an error")
}
// A partial key without CRT values should still parse.
b, _ := asn1.Marshal(struct {
Version int
N *big.Int
E int
D *big.Int
P *big.Int
Q *big.Int
}{
N: priv.N,
E: priv.PublicKey.E,
D: priv.D,
P: priv.Primes[0],
Q: priv.Primes[1],
})
p2, err := ParsePKCS1PrivateKey(b)
if err != nil {
t.Fatalf("parsing partial private key resulted in an error: %v", err)
}
if !p2.Equal(priv) {
t.Errorf("partial private key did not match original key")
}
if p2.Precomputed.Dp == nil || p2.Precomputed.Dq == nil || p2.Precomputed.Qinv == nil {
t.Errorf("precomputed values not recomputed")
}
}
func TestPKCS1MismatchPublicKeyFormat(t *testing.T) {

View File

@ -612,6 +612,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
// Redirect behavior:
redirectMethod string
includeBody = true
stripSensitiveHeaders = false
)
uerr := func(err error) error {
// the body may have been closed already by c.send()
@ -678,7 +679,12 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
// in case the user set Referer on their first request.
// If they really want to override, they can do it in
// their CheckRedirect func.
copyHeaders(req)
if !stripSensitiveHeaders && reqs[0].URL.Host != req.URL.Host {
if !shouldCopyHeaderOnRedirect(reqs[0].URL, req.URL) {
stripSensitiveHeaders = true
}
}
copyHeaders(req, stripSensitiveHeaders)
// Add the Referer header from the most recent
// request URL to the new one, if it's not https->http:
@ -746,7 +752,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
// makeHeadersCopier makes a function that copies headers from the
// initial Request, ireq. For every redirect, this function must be called
// so that it can copy headers into the upcoming Request.
func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
func (c *Client) makeHeadersCopier(ireq *Request) func(req *Request, stripSensitiveHeaders bool) {
// The headers to copy are from the very initial request.
// We use a closured callback to keep a reference to these original headers.
var (
@ -760,8 +766,7 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
}
}
preq := ireq // The previous request
return func(req *Request) {
return func(req *Request, stripSensitiveHeaders bool) {
// If Jar is present and there was some initial cookies provided
// via the request header, then we may need to alter the initial
// cookies as we follow redirects since each redirect may end up
@ -798,12 +803,15 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
// Copy the initial request's Header values
// (at least the safe ones).
for k, vv := range ireqhdr {
if shouldCopyHeaderOnRedirect(k, preq.URL, req.URL) {
sensitive := false
switch CanonicalHeaderKey(k) {
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
sensitive = true
}
if !(sensitive && stripSensitiveHeaders) {
req.Header[k] = vv
}
}
preq = req // Update previous Request with the current request
}
}
@ -979,9 +987,7 @@ func (b *cancelTimerBody) Close() error {
return err
}
func shouldCopyHeaderOnRedirect(headerKey string, initial, dest *url.URL) bool {
switch CanonicalHeaderKey(headerKey) {
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
func shouldCopyHeaderOnRedirect(initial, dest *url.URL) bool {
// Permit sending auth/cookie headers from "foo.com"
// to "sub.foo.com".
@ -999,9 +1005,6 @@ func shouldCopyHeaderOnRedirect(headerKey string, initial, dest *url.URL) bool {
dhost := idnaASCIIFromURL(dest)
return isDomainOrSubdomain(dhost, ihost)
}
// All other headers are copied:
return true
}
// isDomainOrSubdomain reports whether sub is a subdomain (or exact
// match) of the parent domain.

View File

@ -1536,6 +1536,55 @@ func testClientCopyHeadersOnRedirect(t *testing.T, mode testMode) {
}
}
// Issue #70530: Once we strip a header on a redirect to a different host,
// the header should stay stripped across any further redirects.
func TestClientStripHeadersOnRepeatedRedirect(t *testing.T) {
run(t, testClientStripHeadersOnRepeatedRedirect)
}
func testClientStripHeadersOnRepeatedRedirect(t *testing.T, mode testMode) {
var proto string
ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
if r.Host+r.URL.Path != "a.example.com/" {
if h := r.Header.Get("Authorization"); h != "" {
t.Errorf("on request to %v%v, Authorization=%q, want no header", r.Host, r.URL.Path, h)
}
}
// Follow a chain of redirects from a to b and back to a.
// The Authorization header is stripped on the first redirect to b,
// and stays stripped even if we're sent back to a.
switch r.Host + r.URL.Path {
case "a.example.com/":
Redirect(w, r, proto+"://b.example.com/", StatusFound)
case "b.example.com/":
Redirect(w, r, proto+"://b.example.com/redirect", StatusFound)
case "b.example.com/redirect":
Redirect(w, r, proto+"://a.example.com/redirect", StatusFound)
case "a.example.com/redirect":
w.Header().Set("X-Done", "true")
default:
t.Errorf("unexpected request to %v", r.URL)
}
})).ts
proto, _, _ = strings.Cut(ts.URL, ":")
c := ts.Client()
c.Transport.(*Transport).Dial = func(_ string, _ string) (net.Conn, error) {
return net.Dial("tcp", ts.Listener.Addr().String())
}
req, _ := NewRequest("GET", proto+"://a.example.com/", nil)
req.Header.Add("Cookie", "foo=bar")
req.Header.Add("Authorization", "secretpassword")
res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
if res.Header.Get("X-Done") != "true" {
t.Fatalf("response missing expected header: X-Done=true")
}
}
// Issue 22233: copy host when Client follows a relative redirect.
func TestClientCopyHostOnRedirect(t *testing.T) { run(t, testClientCopyHostOnRedirect) }
func testClientCopyHostOnRedirect(t *testing.T, mode testMode) {
@ -1702,43 +1751,39 @@ func testClientAltersCookiesOnRedirect(t *testing.T, mode testMode) {
// Part of Issue 4800
func TestShouldCopyHeaderOnRedirect(t *testing.T) {
tests := []struct {
header string
initialURL string
destURL string
want bool
}{
{"User-Agent", "http://foo.com/", "http://bar.com/", true},
{"X-Foo", "http://foo.com/", "http://bar.com/", true},
// Sensitive headers:
{"cookie", "http://foo.com/", "http://bar.com/", false},
{"cookie2", "http://foo.com/", "http://bar.com/", false},
{"authorization", "http://foo.com/", "http://bar.com/", false},
{"authorization", "http://foo.com/", "https://foo.com/", true},
{"authorization", "http://foo.com:1234/", "http://foo.com:4321/", true},
{"www-authenticate", "http://foo.com/", "http://bar.com/", false},
{"authorization", "http://foo.com/", "http://[::1%25.foo.com]/", false},
{"http://foo.com/", "http://bar.com/", false},
{"http://foo.com/", "http://bar.com/", false},
{"http://foo.com/", "http://bar.com/", false},
{"http://foo.com/", "https://foo.com/", true},
{"http://foo.com:1234/", "http://foo.com:4321/", true},
{"http://foo.com/", "http://bar.com/", false},
{"http://foo.com/", "http://[::1%25.foo.com]/", false},
// But subdomains should work:
{"www-authenticate", "http://foo.com/", "http://foo.com/", true},
{"www-authenticate", "http://foo.com/", "http://sub.foo.com/", true},
{"www-authenticate", "http://foo.com/", "http://notfoo.com/", false},
{"www-authenticate", "http://foo.com/", "https://foo.com/", true},
{"www-authenticate", "http://foo.com:80/", "http://foo.com/", true},
{"www-authenticate", "http://foo.com:80/", "http://sub.foo.com/", true},
{"www-authenticate", "http://foo.com:443/", "https://foo.com/", true},
{"www-authenticate", "http://foo.com:443/", "https://sub.foo.com/", true},
{"www-authenticate", "http://foo.com:1234/", "http://foo.com/", true},
{"http://foo.com/", "http://foo.com/", true},
{"http://foo.com/", "http://sub.foo.com/", true},
{"http://foo.com/", "http://notfoo.com/", false},
{"http://foo.com/", "https://foo.com/", true},
{"http://foo.com:80/", "http://foo.com/", true},
{"http://foo.com:80/", "http://sub.foo.com/", true},
{"http://foo.com:443/", "https://foo.com/", true},
{"http://foo.com:443/", "https://sub.foo.com/", true},
{"http://foo.com:1234/", "http://foo.com/", true},
{"authorization", "http://foo.com/", "http://foo.com/", true},
{"authorization", "http://foo.com/", "http://sub.foo.com/", true},
{"authorization", "http://foo.com/", "http://notfoo.com/", false},
{"authorization", "http://foo.com/", "https://foo.com/", true},
{"authorization", "http://foo.com:80/", "http://foo.com/", true},
{"authorization", "http://foo.com:80/", "http://sub.foo.com/", true},
{"authorization", "http://foo.com:443/", "https://foo.com/", true},
{"authorization", "http://foo.com:443/", "https://sub.foo.com/", true},
{"authorization", "http://foo.com:1234/", "http://foo.com/", true},
{"http://foo.com/", "http://foo.com/", true},
{"http://foo.com/", "http://sub.foo.com/", true},
{"http://foo.com/", "http://notfoo.com/", false},
{"http://foo.com/", "https://foo.com/", true},
{"http://foo.com:80/", "http://foo.com/", true},
{"http://foo.com:80/", "http://sub.foo.com/", true},
{"http://foo.com:443/", "https://foo.com/", true},
{"http://foo.com:443/", "https://sub.foo.com/", true},
{"http://foo.com:1234/", "http://foo.com/", true},
}
for i, tt := range tests {
u0, err := url.Parse(tt.initialURL)
@ -1751,10 +1796,10 @@ func TestShouldCopyHeaderOnRedirect(t *testing.T) {
t.Errorf("%d. dest URL %q parse error: %v", i, tt.destURL, err)
continue
}
got := Export_shouldCopyHeaderOnRedirect(tt.header, u0, u1)
got := Export_shouldCopyHeaderOnRedirect(u0, u1)
if got != tt.want {
t.Errorf("%d. shouldCopyHeaderOnRedirect(%q, %q => %q) = %v; want %v",
i, tt.header, tt.initialURL, tt.destURL, got, tt.want)
t.Errorf("%d. shouldCopyHeaderOnRedirect(%q => %q) = %v; want %v",
i, tt.initialURL, tt.destURL, got, tt.want)
}
}
}

View File

@ -10,56 +10,56 @@ import "strings"
// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
// generated from src/crypto/tls:
// go run generate_cert.go --rsa-bits 2048 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
// go run generate_cert.go --rsa-bits 2048 --host 127.0.0.1,::1,example.com,*.example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
MIIDOTCCAiGgAwIBAgIQSRJrEpBGFc7tNb1fb5pKFzANBgkqhkiG9w0BAQsFADAS
MIIDSDCCAjCgAwIBAgIQEP/md970HysdBTpuzDOf0DANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA6Gba5tHV1dAKouAaXO3/ebDUU4rvwCUg/CNaJ2PT5xLD4N1Vcb8r
bFSW2HXKq+MPfVdwIKR/1DczEoAGf/JWQTW7EgzlXrCd3rlajEX2D73faWJekD0U
aUgz5vtrTXZ90BQL7WvRICd7FlEZ6FPOcPlumiyNmzUqtwGhO+9ad1W5BqJaRI6P
YfouNkwR6Na4TzSj5BrqUfP0FwDizKSJ0XXmh8g8G9mtwxOSN3Ru1QFc61Xyeluk
POGKBV/q6RBNklTNe0gI8usUMlYyoC7ytppNMW7X2vodAelSu25jgx2anj9fDVZu
h7AXF5+4nJS4AAt0n1lNY7nGSsdZas8PbQIDAQABo4GIMIGFMA4GA1UdDwEB/wQE
MIIBCgKCAQEAxcl69ROJdxjN+MJZnbFrYxyQooADCsJ6VDkuMyNQIix/Hk15Nk/u
FyBX1Me++aEpGmY3RIY4fUvELqT/srvAHsTXwVVSttMcY8pcAFmXSqo3x4MuUTG/
jCX3Vftj0r3EM5M8ImY1rzA/jqTTLJg00rD+DmuDABcqQvoXw/RV8w1yTRi5BPoH
DFD/AWTt/YgMvk1l2Yq/xI8VbMUIpjBoGXxWsSevQ5i2s1mk9/yZzu0Ysp1tTlzD
qOPa4ysFjBitdXiwfxjxtv5nXqOCP5rheKO0sWLk0fetMp1OV5JSJMAJw6c2ZMkl
U2WMqAEpRjdE/vHfIuNg+yGaRRqI07NZRQIDAQABo4GXMIGUMA4GA1UdDwEB/wQE
AwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
DgQWBBStsdjh3/JCXXYlQryOrL4Sh7BW5TAuBgNVHREEJzAlggtleGFtcGxlLmNv
bYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAxWGI
5NhpF3nwwy/4yB4i/CwwSpLrWUa70NyhvprUBC50PxiXav1TeDzwzLx/o5HyNwsv
cxv3HdkLW59i/0SlJSrNnWdfZ19oTcS+6PtLoVyISgtyN6DpkKpdG1cOkW3Cy2P2
+tK/tKHRP1Y/Ra0RiDpOAmqn0gCOFGz8+lqDIor/T7MTpibL3IxqWfPrvfVRHL3B
grw/ZQTTIVjjh4JBSW3WyWgNo/ikC1lrVxzl4iPUGptxT36Cr7Zk2Bsg0XqwbOvK
5d+NTDREkSnUbie4GeutujmX3Dsx88UiV6UY/4lHJa6I5leHUNOHahRbpbWeOfs/
WkBKOclmOV2xlTVuPw==
DgQWBBQR5QIzmacmw78ZI1C4MXw7Q0wJ1jA9BgNVHREENjA0ggtleGFtcGxlLmNv
bYINKi5leGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG
9w0BAQsFAAOCAQEACrRNgiioUDzxQftd0fwOa6iRRcPampZRDtuaF68yNHoNWbOu
LUwc05eOWxRq3iABGSk2xg+FXM3DDeW4HhAhCFptq7jbVZ+4Jj6HeJG9mYRatAxR
Y/dEpa0D0EHhDxxVg6UzKOXB355n0IetGE/aWvyTV9SiDs6QsaC57Q9qq1/mitx5
2GFBoapol9L5FxCc77bztzK8CpLujkBi25Vk6GAFbl27opLfpyxkM+rX/T6MXCPO
6/YBacNZ7ff1/57Etg4i5mNA6ubCpuc4Gi9oYqCNNohftr2lkJr7REdDR6OW0lsL
rF7r4gUnKeC7mYIH1zypY7laskopiLFAfe96Kg==
-----END CERTIFICATE-----`)
// LocalhostKey is the private key for LocalhostCert.
var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoZtrm0dXV0Aqi
4Bpc7f95sNRTiu/AJSD8I1onY9PnEsPg3VVxvytsVJbYdcqr4w99V3AgpH/UNzMS
gAZ/8lZBNbsSDOVesJ3euVqMRfYPvd9pYl6QPRRpSDPm+2tNdn3QFAvta9EgJ3sW
URnoU85w+W6aLI2bNSq3AaE771p3VbkGolpEjo9h+i42TBHo1rhPNKPkGupR8/QX
AOLMpInRdeaHyDwb2a3DE5I3dG7VAVzrVfJ6W6Q84YoFX+rpEE2SVM17SAjy6xQy
VjKgLvK2mk0xbtfa+h0B6VK7bmODHZqeP18NVm6HsBcXn7iclLgAC3SfWU1jucZK
x1lqzw9tAgMBAAECggEABWzxS1Y2wckblnXY57Z+sl6YdmLV+gxj2r8Qib7g4ZIk
lIlWR1OJNfw7kU4eryib4fc6nOh6O4AWZyYqAK6tqNQSS/eVG0LQTLTTEldHyVJL
dvBe+MsUQOj4nTndZW+QvFzbcm2D8lY5n2nBSxU5ypVoKZ1EqQzytFcLZpTN7d89
EPj0qDyrV4NZlWAwL1AygCwnlwhMQjXEalVF1ylXwU3QzyZ/6MgvF6d3SSUlh+sq
XefuyigXw484cQQgbzopv6niMOmGP3of+yV4JQqUSb3IDmmT68XjGd2Dkxl4iPki
6ZwXf3CCi+c+i/zVEcufgZ3SLf8D99kUGE7v7fZ6AQKBgQD1ZX3RAla9hIhxCf+O
3D+I1j2LMrdjAh0ZKKqwMR4JnHX3mjQI6LwqIctPWTU8wYFECSh9klEclSdCa64s
uI/GNpcqPXejd0cAAdqHEEeG5sHMDt0oFSurL4lyud0GtZvwlzLuwEweuDtvT9cJ
Wfvl86uyO36IW8JdvUprYDctrQKBgQDycZ697qutBieZlGkHpnYWUAeImVA878sJ
w44NuXHvMxBPz+lbJGAg8Cn8fcxNAPqHIraK+kx3po8cZGQywKHUWsxi23ozHoxo
+bGqeQb9U661TnfdDspIXia+xilZt3mm5BPzOUuRqlh4Y9SOBpSWRmEhyw76w4ZP
OPxjWYAgwQKBgA/FehSYxeJgRjSdo+MWnK66tjHgDJE8bYpUZsP0JC4R9DL5oiaA
brd2fI6Y+SbyeNBallObt8LSgzdtnEAbjIH8uDJqyOmknNePRvAvR6mP4xyuR+Bv
m+Lgp0DMWTw5J9CKpydZDItc49T/mJ5tPhdFVd+am0NAQnmr1MCZ6nHxAoGABS3Y
LkaC9FdFUUqSU8+Chkd/YbOkuyiENdkvl6t2e52jo5DVc1T7mLiIrRQi4SI8N9bN
/3oJWCT+uaSLX2ouCtNFunblzWHBrhxnZzTeqVq4SLc8aESAnbslKL4i8/+vYZlN
s8xtiNcSvL+lMsOBORSXzpj/4Ot8WwTkn1qyGgECgYBKNTypzAHeLE6yVadFp3nQ
Ckq9yzvP/ib05rvgbvrne00YeOxqJ9gtTrzgh7koqJyX1L4NwdkEza4ilDWpucn0
xiUZS4SoaJq6ZvcBYS62Yr1t8n09iG47YL8ibgtmH3L+svaotvpVxVK+d7BLevA/
ZboOWVe3icTy64BT3OQhmg==
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFyXr1E4l3GM34
wlmdsWtjHJCigAMKwnpUOS4zI1AiLH8eTXk2T+4XIFfUx775oSkaZjdEhjh9S8Qu
pP+yu8AexNfBVVK20xxjylwAWZdKqjfHgy5RMb+MJfdV+2PSvcQzkzwiZjWvMD+O
pNMsmDTSsP4Oa4MAFypC+hfD9FXzDXJNGLkE+gcMUP8BZO39iAy+TWXZir/EjxVs
xQimMGgZfFaxJ69DmLazWaT3/JnO7RiynW1OXMOo49rjKwWMGK11eLB/GPG2/mde
o4I/muF4o7SxYuTR960ynU5XklIkwAnDpzZkySVTZYyoASlGN0T+8d8i42D7IZpF
GojTs1lFAgMBAAECggEAIYthUi1lFBDd5gG4Rzlu+BlBIn5JhcqkCqLEBiJIFfOr
/4yuMRrvS3bNzqWt6xJ9MSAC4ZlN/VobRLnxL/QNymoiGYUKCT3Ww8nvPpPzR9OE
sE68TUL9tJw/zZJcRMKwgvrGqSLimfq53MxxkE+kLdOc0v9C8YH8Re26mB5ZcWYa
7YFyZQpKsQYnsmu/05cMbpOQrQWhtmIqRoyn8mG/par2s3NzjtpSE9NINyz26uFc
k/3ovFJQIHkUmTS7KHD3BgY5vuCqP98HramYnOysJ0WoYgvSDNCWw3037s5CCwJT
gCKuM+Ow6liFrj83RrdKBpm5QUGjfNpYP31o+QNP4QKBgQDSrUQ2XdgtAnibAV7u
7kbxOxro0EhIKso0Y/6LbDQgcXgxLqltkmeqZgG8nC3Z793lhlSasz2snhzzooV5
5fTy1y8ikXqjhG0nNkInFyOhsI0auE28CFoDowaQd+5cmCatpN4Grqo5PNRXxm1w
HktfPEgoP11NNCFHvvN5fEKbbQKBgQDwVlOaV20IvW3IPq7cXZyiyabouFF9eTRo
VJka1Uv+JtyvL2P0NKkjYHOdN8gRblWqxQtJoTNk020rVA4UP1heiXALy50gvj/p
hMcybPTLYSPOhAGx838KIcvGR5oskP1aUCmFbFQzGELxhJ9diVVjxUtbG2DuwPKd
tD9TLxT2OQKBgQCcdlHSjp+dzdgERmBa0ludjGfPv9/uuNizUBAbO6D690psPFtY
JQMYaemgSd1DngEOFVWADt4e9M5Lose+YCoqr+UxpxmNlyv5kzJOFcFAs/4XeglB
PHKdgNW/NVKxMc6H54l9LPr+x05sYdGlEtqnP/3W5jhEvhJ5Vjc8YiyVgQKBgQCl
zwjyrGo+42GACy7cPYE5FeIfIDqoVByB9guC5bD98JXEDu/opQQjsgFRcBCJZhOY
M0UsURiB8ROaFu13rpQq9KrmmF0ZH+g8FSzQbzcbsTLg4VXCDXmR5esOKowFPypr
Sm667BfTAGP++D5ya7MLmCv6+RKQ5XD8uEQQAaV2kQKBgAD8qeJuWIXZT0VKkQrn
nIhgtzGERF/6sZdQGW2LxTbUDWG74AfFkkEbeBfwEkCZXY/xmnYqYABhvlSex8jU
supU6Eea21esIxIub2zv/Np0ojUb6rlqTPS4Ox1E27D787EJ3VOXpriSD10vyNnZ
jel6uj2FOP9g54s+GzlSVg/T
-----END RSA TESTING KEY-----`))
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }