build(deps): bump cloud.google.com/go/compute from 1.10.0 to 1.19.3
Bumps [cloud.google.com/go/compute](https://github.com/googleapis/google-cloud-go) from 1.10.0 to 1.19.3. - [Release notes](https://github.com/googleapis/google-cloud-go/releases) - [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/documentai/CHANGES.md) - [Commits](https://github.com/googleapis/google-cloud-go/compare/kms/v1.10.0...compute/v1.19.3) --- updated-dependencies: - dependency-name: cloud.google.com/go/compute dependency-type: direct:production update-type: version-update:semver-minor ... Migrated to the new version by following https://github.com/googleapis/google-cloud-go/blob/main/migration.md Co-authored-by: Tomáš Hozza <thozza@redhat.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Tomáš Hozza <thozza@redhat.com>
This commit is contained in:
parent
468c63d433
commit
60e55b5ed3
448 changed files with 119170 additions and 54581 deletions
31
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
31
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
|
|
@ -3,8 +3,7 @@
|
|||
[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
|
||||
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)
|
||||
|
||||
xxhash is a Go implementation of the 64-bit
|
||||
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
|
||||
xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
|
||||
high-quality hashing algorithm that is much faster than anything in the Go
|
||||
standard library.
|
||||
|
||||
|
|
@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error)
|
|||
func (*Digest) Sum64() uint64
|
||||
```
|
||||
|
||||
This implementation provides a fast pure-Go implementation and an even faster
|
||||
assembly implementation for amd64.
|
||||
The package is written with optimized pure Go and also contains even faster
|
||||
assembly implementations for amd64 and arm64. If desired, the `purego` build tag
|
||||
opts into using the Go code even on those architectures.
|
||||
|
||||
[xxHash]: http://cyan4973.github.io/xxHash/
|
||||
|
||||
## Compatibility
|
||||
|
||||
|
|
@ -45,19 +47,20 @@ I recommend using the latest release of Go.
|
|||
Here are some quick benchmarks comparing the pure-Go and assembly
|
||||
implementations of Sum64.
|
||||
|
||||
| input size | purego | asm |
|
||||
| --- | --- | --- |
|
||||
| 5 B | 979.66 MB/s | 1291.17 MB/s |
|
||||
| 100 B | 7475.26 MB/s | 7973.40 MB/s |
|
||||
| 4 KB | 17573.46 MB/s | 17602.65 MB/s |
|
||||
| 10 MB | 17131.46 MB/s | 17142.16 MB/s |
|
||||
| input size | purego | asm |
|
||||
| ---------- | --------- | --------- |
|
||||
| 4 B | 1.3 GB/s | 1.2 GB/s |
|
||||
| 16 B | 2.9 GB/s | 3.5 GB/s |
|
||||
| 100 B | 6.9 GB/s | 8.1 GB/s |
|
||||
| 4 KB | 11.7 GB/s | 16.7 GB/s |
|
||||
| 10 MB | 12.0 GB/s | 17.3 GB/s |
|
||||
|
||||
These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using
|
||||
the following commands under Go 1.11.2:
|
||||
These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
|
||||
CPU using the following commands under Go 1.19.2:
|
||||
|
||||
```
|
||||
$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes'
|
||||
$ go test -benchtime 10s -bench '/xxhash,direct,bytes'
|
||||
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||
```
|
||||
|
||||
## Projects using this package
|
||||
|
|
|
|||
10
vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
10
vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
set -eu -o pipefail
|
||||
|
||||
# Small convenience script for running the tests with various combinations of
|
||||
# arch/tags. This assumes we're running on amd64 and have qemu available.
|
||||
|
||||
go test ./...
|
||||
go test -tags purego ./...
|
||||
GOARCH=arm64 go test
|
||||
GOARCH=arm64 go test -tags purego
|
||||
47
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
47
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
|
|
@ -16,19 +16,11 @@ const (
|
|||
prime5 uint64 = 2870177450012600261
|
||||
)
|
||||
|
||||
// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
|
||||
// possible in the Go code is worth a small (but measurable) performance boost
|
||||
// by avoiding some MOVQs. Vars are needed for the asm and also are useful for
|
||||
// convenience in the Go code in a few places where we need to intentionally
|
||||
// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
|
||||
// result overflows a uint64).
|
||||
var (
|
||||
prime1v = prime1
|
||||
prime2v = prime2
|
||||
prime3v = prime3
|
||||
prime4v = prime4
|
||||
prime5v = prime5
|
||||
)
|
||||
// Store the primes in an array as well.
|
||||
//
|
||||
// The consts are used when possible in Go code to avoid MOVs but we need a
|
||||
// contiguous array of the assembly code.
|
||||
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
|
||||
|
||||
// Digest implements hash.Hash64.
|
||||
type Digest struct {
|
||||
|
|
@ -50,10 +42,10 @@ func New() *Digest {
|
|||
|
||||
// Reset clears the Digest's state so that it can be reused.
|
||||
func (d *Digest) Reset() {
|
||||
d.v1 = prime1v + prime2
|
||||
d.v1 = primes[0] + prime2
|
||||
d.v2 = prime2
|
||||
d.v3 = 0
|
||||
d.v4 = -prime1v
|
||||
d.v4 = -primes[0]
|
||||
d.total = 0
|
||||
d.n = 0
|
||||
}
|
||||
|
|
@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) {
|
|||
n = len(b)
|
||||
d.total += uint64(n)
|
||||
|
||||
memleft := d.mem[d.n&(len(d.mem)-1):]
|
||||
|
||||
if d.n+n < 32 {
|
||||
// This new data doesn't even fill the current block.
|
||||
copy(d.mem[d.n:], b)
|
||||
copy(memleft, b)
|
||||
d.n += n
|
||||
return
|
||||
}
|
||||
|
||||
if d.n > 0 {
|
||||
// Finish off the partial block.
|
||||
copy(d.mem[d.n:], b)
|
||||
c := copy(memleft, b)
|
||||
d.v1 = round(d.v1, u64(d.mem[0:8]))
|
||||
d.v2 = round(d.v2, u64(d.mem[8:16]))
|
||||
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
||||
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
||||
b = b[32-d.n:]
|
||||
b = b[c:]
|
||||
d.n = 0
|
||||
}
|
||||
|
||||
|
|
@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 {
|
|||
|
||||
h += d.total
|
||||
|
||||
i, end := 0, d.n
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(d.mem[i:i+8]))
|
||||
b := d.mem[:d.n&(len(d.mem)-1)]
|
||||
for ; len(b) >= 8; b = b[8:] {
|
||||
k1 := round(0, u64(b[:8]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(d.mem[i:i+4])) * prime1
|
||||
if len(b) >= 4 {
|
||||
h ^= uint64(u32(b[:4])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
b = b[4:]
|
||||
}
|
||||
for i < end {
|
||||
h ^= uint64(d.mem[i]) * prime5
|
||||
for ; len(b) > 0; b = b[1:] {
|
||||
h ^= uint64(b[0]) * prime5
|
||||
h = rol11(h) * prime1
|
||||
i++
|
||||
}
|
||||
|
||||
h ^= h >> 33
|
||||
|
|
|
|||
308
vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
308
vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
|
|
@ -1,215 +1,209 @@
|
|||
//go:build !appengine && gc && !purego
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Register allocation:
|
||||
// AX h
|
||||
// SI pointer to advance through b
|
||||
// DX n
|
||||
// BX loop end
|
||||
// R8 v1, k1
|
||||
// R9 v2
|
||||
// R10 v3
|
||||
// R11 v4
|
||||
// R12 tmp
|
||||
// R13 prime1v
|
||||
// R14 prime2v
|
||||
// DI prime4v
|
||||
// Registers:
|
||||
#define h AX
|
||||
#define d AX
|
||||
#define p SI // pointer to advance through b
|
||||
#define n DX
|
||||
#define end BX // loop end
|
||||
#define v1 R8
|
||||
#define v2 R9
|
||||
#define v3 R10
|
||||
#define v4 R11
|
||||
#define x R12
|
||||
#define prime1 R13
|
||||
#define prime2 R14
|
||||
#define prime4 DI
|
||||
|
||||
// round reads from and advances the buffer pointer in SI.
|
||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
||||
#define round(r) \
|
||||
MOVQ (SI), R12 \
|
||||
ADDQ $8, SI \
|
||||
IMULQ R14, R12 \
|
||||
ADDQ R12, r \
|
||||
ROLQ $31, r \
|
||||
IMULQ R13, r
|
||||
#define round(acc, x) \
|
||||
IMULQ prime2, x \
|
||||
ADDQ x, acc \
|
||||
ROLQ $31, acc \
|
||||
IMULQ prime1, acc
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and val.
|
||||
// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
|
||||
#define mergeRound(acc, val) \
|
||||
IMULQ R14, val \
|
||||
ROLQ $31, val \
|
||||
IMULQ R13, val \
|
||||
XORQ val, acc \
|
||||
IMULQ R13, acc \
|
||||
ADDQ DI, acc
|
||||
// round0 performs the operation x = round(0, x).
|
||||
#define round0(x) \
|
||||
IMULQ prime2, x \
|
||||
ROLQ $31, x \
|
||||
IMULQ prime1, x
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and x.
|
||||
// It assumes that prime1, prime2, and prime4 have been loaded.
|
||||
#define mergeRound(acc, x) \
|
||||
round0(x) \
|
||||
XORQ x, acc \
|
||||
IMULQ prime1, acc \
|
||||
ADDQ prime4, acc
|
||||
|
||||
// blockLoop processes as many 32-byte blocks as possible,
|
||||
// updating v1, v2, v3, and v4. It assumes that there is at least one block
|
||||
// to process.
|
||||
#define blockLoop() \
|
||||
loop: \
|
||||
MOVQ +0(p), x \
|
||||
round(v1, x) \
|
||||
MOVQ +8(p), x \
|
||||
round(v2, x) \
|
||||
MOVQ +16(p), x \
|
||||
round(v3, x) \
|
||||
MOVQ +24(p), x \
|
||||
round(v4, x) \
|
||||
ADDQ $32, p \
|
||||
CMPQ p, end \
|
||||
JLE loop
|
||||
|
||||
// func Sum64(b []byte) uint64
|
||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
||||
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||
// Load fixed primes.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·prime4v(SB), DI
|
||||
MOVQ ·primes+0(SB), prime1
|
||||
MOVQ ·primes+8(SB), prime2
|
||||
MOVQ ·primes+24(SB), prime4
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+0(FP), SI
|
||||
MOVQ b_len+8(FP), DX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
MOVQ b_base+0(FP), p
|
||||
MOVQ b_len+8(FP), n
|
||||
LEAQ (p)(n*1), end
|
||||
|
||||
// The first loop limit will be len(b)-32.
|
||||
SUBQ $32, BX
|
||||
SUBQ $32, end
|
||||
|
||||
// Check whether we have at least one block.
|
||||
CMPQ DX, $32
|
||||
CMPQ n, $32
|
||||
JLT noBlocks
|
||||
|
||||
// Set up initial state (v1, v2, v3, v4).
|
||||
MOVQ R13, R8
|
||||
ADDQ R14, R8
|
||||
MOVQ R14, R9
|
||||
XORQ R10, R10
|
||||
XORQ R11, R11
|
||||
SUBQ R13, R11
|
||||
MOVQ prime1, v1
|
||||
ADDQ prime2, v1
|
||||
MOVQ prime2, v2
|
||||
XORQ v3, v3
|
||||
XORQ v4, v4
|
||||
SUBQ prime1, v4
|
||||
|
||||
// Loop until SI > BX.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
blockLoop()
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
MOVQ v1, h
|
||||
ROLQ $1, h
|
||||
MOVQ v2, x
|
||||
ROLQ $7, x
|
||||
ADDQ x, h
|
||||
MOVQ v3, x
|
||||
ROLQ $12, x
|
||||
ADDQ x, h
|
||||
MOVQ v4, x
|
||||
ROLQ $18, x
|
||||
ADDQ x, h
|
||||
|
||||
MOVQ R8, AX
|
||||
ROLQ $1, AX
|
||||
MOVQ R9, R12
|
||||
ROLQ $7, R12
|
||||
ADDQ R12, AX
|
||||
MOVQ R10, R12
|
||||
ROLQ $12, R12
|
||||
ADDQ R12, AX
|
||||
MOVQ R11, R12
|
||||
ROLQ $18, R12
|
||||
ADDQ R12, AX
|
||||
|
||||
mergeRound(AX, R8)
|
||||
mergeRound(AX, R9)
|
||||
mergeRound(AX, R10)
|
||||
mergeRound(AX, R11)
|
||||
mergeRound(h, v1)
|
||||
mergeRound(h, v2)
|
||||
mergeRound(h, v3)
|
||||
mergeRound(h, v4)
|
||||
|
||||
JMP afterBlocks
|
||||
|
||||
noBlocks:
|
||||
MOVQ ·prime5v(SB), AX
|
||||
MOVQ ·primes+32(SB), h
|
||||
|
||||
afterBlocks:
|
||||
ADDQ DX, AX
|
||||
ADDQ n, h
|
||||
|
||||
// Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
|
||||
ADDQ $24, BX
|
||||
ADDQ $24, end
|
||||
CMPQ p, end
|
||||
JG try4
|
||||
|
||||
CMPQ SI, BX
|
||||
JG fourByte
|
||||
loop8:
|
||||
MOVQ (p), x
|
||||
ADDQ $8, p
|
||||
round0(x)
|
||||
XORQ x, h
|
||||
ROLQ $27, h
|
||||
IMULQ prime1, h
|
||||
ADDQ prime4, h
|
||||
|
||||
wordLoop:
|
||||
// Calculate k1.
|
||||
MOVQ (SI), R8
|
||||
ADDQ $8, SI
|
||||
IMULQ R14, R8
|
||||
ROLQ $31, R8
|
||||
IMULQ R13, R8
|
||||
CMPQ p, end
|
||||
JLE loop8
|
||||
|
||||
XORQ R8, AX
|
||||
ROLQ $27, AX
|
||||
IMULQ R13, AX
|
||||
ADDQ DI, AX
|
||||
try4:
|
||||
ADDQ $4, end
|
||||
CMPQ p, end
|
||||
JG try1
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE wordLoop
|
||||
MOVL (p), x
|
||||
ADDQ $4, p
|
||||
IMULQ prime1, x
|
||||
XORQ x, h
|
||||
|
||||
fourByte:
|
||||
ADDQ $4, BX
|
||||
CMPQ SI, BX
|
||||
JG singles
|
||||
ROLQ $23, h
|
||||
IMULQ prime2, h
|
||||
ADDQ ·primes+16(SB), h
|
||||
|
||||
MOVL (SI), R8
|
||||
ADDQ $4, SI
|
||||
IMULQ R13, R8
|
||||
XORQ R8, AX
|
||||
|
||||
ROLQ $23, AX
|
||||
IMULQ R14, AX
|
||||
ADDQ ·prime3v(SB), AX
|
||||
|
||||
singles:
|
||||
ADDQ $4, BX
|
||||
CMPQ SI, BX
|
||||
try1:
|
||||
ADDQ $4, end
|
||||
CMPQ p, end
|
||||
JGE finalize
|
||||
|
||||
singlesLoop:
|
||||
MOVBQZX (SI), R12
|
||||
ADDQ $1, SI
|
||||
IMULQ ·prime5v(SB), R12
|
||||
XORQ R12, AX
|
||||
loop1:
|
||||
MOVBQZX (p), x
|
||||
ADDQ $1, p
|
||||
IMULQ ·primes+32(SB), x
|
||||
XORQ x, h
|
||||
ROLQ $11, h
|
||||
IMULQ prime1, h
|
||||
|
||||
ROLQ $11, AX
|
||||
IMULQ R13, AX
|
||||
|
||||
CMPQ SI, BX
|
||||
JL singlesLoop
|
||||
CMPQ p, end
|
||||
JL loop1
|
||||
|
||||
finalize:
|
||||
MOVQ AX, R12
|
||||
SHRQ $33, R12
|
||||
XORQ R12, AX
|
||||
IMULQ R14, AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $29, R12
|
||||
XORQ R12, AX
|
||||
IMULQ ·prime3v(SB), AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $32, R12
|
||||
XORQ R12, AX
|
||||
MOVQ h, x
|
||||
SHRQ $33, x
|
||||
XORQ x, h
|
||||
IMULQ prime2, h
|
||||
MOVQ h, x
|
||||
SHRQ $29, x
|
||||
XORQ x, h
|
||||
IMULQ ·primes+16(SB), h
|
||||
MOVQ h, x
|
||||
SHRQ $32, x
|
||||
XORQ x, h
|
||||
|
||||
MOVQ AX, ret+24(FP)
|
||||
MOVQ h, ret+24(FP)
|
||||
RET
|
||||
|
||||
// writeBlocks uses the same registers as above except that it uses AX to store
|
||||
// the d pointer.
|
||||
|
||||
// func writeBlocks(d *Digest, b []byte) int
|
||||
TEXT ·writeBlocks(SB), NOSPLIT, $0-40
|
||||
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||
// Load fixed primes needed for round.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·primes+0(SB), prime1
|
||||
MOVQ ·primes+8(SB), prime2
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+8(FP), SI
|
||||
MOVQ b_len+16(FP), DX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
SUBQ $32, BX
|
||||
MOVQ b_base+8(FP), p
|
||||
MOVQ b_len+16(FP), n
|
||||
LEAQ (p)(n*1), end
|
||||
SUBQ $32, end
|
||||
|
||||
// Load vN from d.
|
||||
MOVQ d+0(FP), AX
|
||||
MOVQ 0(AX), R8 // v1
|
||||
MOVQ 8(AX), R9 // v2
|
||||
MOVQ 16(AX), R10 // v3
|
||||
MOVQ 24(AX), R11 // v4
|
||||
MOVQ s+0(FP), d
|
||||
MOVQ 0(d), v1
|
||||
MOVQ 8(d), v2
|
||||
MOVQ 16(d), v3
|
||||
MOVQ 24(d), v4
|
||||
|
||||
// We don't need to check the loop condition here; this function is
|
||||
// always called with at least one block of data to process.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
blockLoop()
|
||||
|
||||
// Copy vN back to d.
|
||||
MOVQ R8, 0(AX)
|
||||
MOVQ R9, 8(AX)
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R11, 24(AX)
|
||||
MOVQ v1, 0(d)
|
||||
MOVQ v2, 8(d)
|
||||
MOVQ v3, 16(d)
|
||||
MOVQ v4, 24(d)
|
||||
|
||||
// The number of bytes written is SI minus the old base pointer.
|
||||
SUBQ b_base+8(FP), SI
|
||||
MOVQ SI, ret+32(FP)
|
||||
// The number of bytes written is p minus the old base pointer.
|
||||
SUBQ b_base+8(FP), p
|
||||
MOVQ p, ret+32(FP)
|
||||
|
||||
RET
|
||||
|
|
|
|||
183
vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
183
vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
//go:build !appengine && gc && !purego
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Registers:
|
||||
#define digest R1
|
||||
#define h R2 // return value
|
||||
#define p R3 // input pointer
|
||||
#define n R4 // input length
|
||||
#define nblocks R5 // n / 32
|
||||
#define prime1 R7
|
||||
#define prime2 R8
|
||||
#define prime3 R9
|
||||
#define prime4 R10
|
||||
#define prime5 R11
|
||||
#define v1 R12
|
||||
#define v2 R13
|
||||
#define v3 R14
|
||||
#define v4 R15
|
||||
#define x1 R20
|
||||
#define x2 R21
|
||||
#define x3 R22
|
||||
#define x4 R23
|
||||
|
||||
#define round(acc, x) \
|
||||
MADD prime2, acc, x, acc \
|
||||
ROR $64-31, acc \
|
||||
MUL prime1, acc
|
||||
|
||||
// round0 performs the operation x = round(0, x).
|
||||
#define round0(x) \
|
||||
MUL prime2, x \
|
||||
ROR $64-31, x \
|
||||
MUL prime1, x
|
||||
|
||||
#define mergeRound(acc, x) \
|
||||
round0(x) \
|
||||
EOR x, acc \
|
||||
MADD acc, prime4, prime1, acc
|
||||
|
||||
// blockLoop processes as many 32-byte blocks as possible,
|
||||
// updating v1, v2, v3, and v4. It assumes that n >= 32.
|
||||
#define blockLoop() \
|
||||
LSR $5, n, nblocks \
|
||||
PCALIGN $16 \
|
||||
loop: \
|
||||
LDP.P 16(p), (x1, x2) \
|
||||
LDP.P 16(p), (x3, x4) \
|
||||
round(v1, x1) \
|
||||
round(v2, x2) \
|
||||
round(v3, x3) \
|
||||
round(v4, x4) \
|
||||
SUB $1, nblocks \
|
||||
CBNZ nblocks, loop
|
||||
|
||||
// func Sum64(b []byte) uint64
|
||||
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||
LDP b_base+0(FP), (p, n)
|
||||
|
||||
LDP ·primes+0(SB), (prime1, prime2)
|
||||
LDP ·primes+16(SB), (prime3, prime4)
|
||||
MOVD ·primes+32(SB), prime5
|
||||
|
||||
CMP $32, n
|
||||
CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }
|
||||
BLT afterLoop
|
||||
|
||||
ADD prime1, prime2, v1
|
||||
MOVD prime2, v2
|
||||
MOVD $0, v3
|
||||
NEG prime1, v4
|
||||
|
||||
blockLoop()
|
||||
|
||||
ROR $64-1, v1, x1
|
||||
ROR $64-7, v2, x2
|
||||
ADD x1, x2
|
||||
ROR $64-12, v3, x3
|
||||
ROR $64-18, v4, x4
|
||||
ADD x3, x4
|
||||
ADD x2, x4, h
|
||||
|
||||
mergeRound(h, v1)
|
||||
mergeRound(h, v2)
|
||||
mergeRound(h, v3)
|
||||
mergeRound(h, v4)
|
||||
|
||||
afterLoop:
|
||||
ADD n, h
|
||||
|
||||
TBZ $4, n, try8
|
||||
LDP.P 16(p), (x1, x2)
|
||||
|
||||
round0(x1)
|
||||
|
||||
// NOTE: here and below, sequencing the EOR after the ROR (using a
|
||||
// rotated register) is worth a small but measurable speedup for small
|
||||
// inputs.
|
||||
ROR $64-27, h
|
||||
EOR x1 @> 64-27, h, h
|
||||
MADD h, prime4, prime1, h
|
||||
|
||||
round0(x2)
|
||||
ROR $64-27, h
|
||||
EOR x2 @> 64-27, h, h
|
||||
MADD h, prime4, prime1, h
|
||||
|
||||
try8:
|
||||
TBZ $3, n, try4
|
||||
MOVD.P 8(p), x1
|
||||
|
||||
round0(x1)
|
||||
ROR $64-27, h
|
||||
EOR x1 @> 64-27, h, h
|
||||
MADD h, prime4, prime1, h
|
||||
|
||||
try4:
|
||||
TBZ $2, n, try2
|
||||
MOVWU.P 4(p), x2
|
||||
|
||||
MUL prime1, x2
|
||||
ROR $64-23, h
|
||||
EOR x2 @> 64-23, h, h
|
||||
MADD h, prime3, prime2, h
|
||||
|
||||
try2:
|
||||
TBZ $1, n, try1
|
||||
MOVHU.P 2(p), x3
|
||||
AND $255, x3, x1
|
||||
LSR $8, x3, x2
|
||||
|
||||
MUL prime5, x1
|
||||
ROR $64-11, h
|
||||
EOR x1 @> 64-11, h, h
|
||||
MUL prime1, h
|
||||
|
||||
MUL prime5, x2
|
||||
ROR $64-11, h
|
||||
EOR x2 @> 64-11, h, h
|
||||
MUL prime1, h
|
||||
|
||||
try1:
|
||||
TBZ $0, n, finalize
|
||||
MOVBU (p), x4
|
||||
|
||||
MUL prime5, x4
|
||||
ROR $64-11, h
|
||||
EOR x4 @> 64-11, h, h
|
||||
MUL prime1, h
|
||||
|
||||
finalize:
|
||||
EOR h >> 33, h
|
||||
MUL prime2, h
|
||||
EOR h >> 29, h
|
||||
MUL prime3, h
|
||||
EOR h >> 32, h
|
||||
|
||||
MOVD h, ret+24(FP)
|
||||
RET
|
||||
|
||||
// func writeBlocks(d *Digest, b []byte) int
|
||||
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||
LDP ·primes+0(SB), (prime1, prime2)
|
||||
|
||||
// Load state. Assume v[1-4] are stored contiguously.
|
||||
MOVD d+0(FP), digest
|
||||
LDP 0(digest), (v1, v2)
|
||||
LDP 16(digest), (v3, v4)
|
||||
|
||||
LDP b_base+8(FP), (p, n)
|
||||
|
||||
blockLoop()
|
||||
|
||||
// Store updated state.
|
||||
STP (v1, v2), 0(digest)
|
||||
STP (v3, v4), 16(digest)
|
||||
|
||||
BIC $31, n
|
||||
MOVD n, ret+32(FP)
|
||||
RET
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
//go:build (amd64 || arm64) && !appengine && gc && !purego
|
||||
// +build amd64 arm64
|
||||
// +build !appengine
|
||||
// +build gc
|
||||
// +build !purego
|
||||
22
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
22
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
|
|
@ -1,4 +1,5 @@
|
|||
// +build !amd64 appengine !gc purego
|
||||
//go:build (!amd64 && !arm64) || appengine || !gc || purego
|
||||
// +build !amd64,!arm64 appengine !gc purego
|
||||
|
||||
package xxhash
|
||||
|
||||
|
|
@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 {
|
|||
var h uint64
|
||||
|
||||
if n >= 32 {
|
||||
v1 := prime1v + prime2
|
||||
v1 := primes[0] + prime2
|
||||
v2 := prime2
|
||||
v3 := uint64(0)
|
||||
v4 := -prime1v
|
||||
v4 := -primes[0]
|
||||
for len(b) >= 32 {
|
||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||
|
|
@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 {
|
|||
|
||||
h += uint64(n)
|
||||
|
||||
i, end := 0, len(b)
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(b[i:i+8:len(b)]))
|
||||
for ; len(b) >= 8; b = b[8:] {
|
||||
k1 := round(0, u64(b[:8]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
|
||||
if len(b) >= 4 {
|
||||
h ^= uint64(u32(b[:4])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
b = b[4:]
|
||||
}
|
||||
for ; i < end; i++ {
|
||||
h ^= uint64(b[i]) * prime5
|
||||
for ; len(b) > 0; b = b[1:] {
|
||||
h ^= uint64(b[0]) * prime5
|
||||
h = rol11(h) * prime1
|
||||
}
|
||||
|
||||
|
|
|
|||
1
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
1
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
|
|
@ -1,3 +1,4 @@
|
|||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
// This file contains the safe implementations of otherwise unsafe-using code.
|
||||
|
|
|
|||
3
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
3
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !appengine
|
||||
// +build !appengine
|
||||
|
||||
// This file encapsulates usage of unsafe.
|
||||
|
|
@ -11,7 +12,7 @@ import (
|
|||
|
||||
// In the future it's possible that compiler optimizations will make these
|
||||
// XxxString functions unnecessary by realizing that calls such as
|
||||
// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205.
|
||||
// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.
|
||||
// If that happens, even if we keep these functions they can be replaced with
|
||||
// the trivial safe code.
|
||||
|
||||
|
|
|
|||
1229
vendor/github.com/golang/glog/glog.go
generated
vendored
1229
vendor/github.com/golang/glog/glog.go
generated
vendored
File diff suppressed because it is too large
Load diff
305
vendor/github.com/golang/glog/glog_file.go
generated
vendored
305
vendor/github.com/golang/glog/glog_file.go
generated
vendored
|
|
@ -1,6 +1,6 @@
|
|||
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
|
||||
// Go support for leveled logs, analogous to https://github.com/google/glog.
|
||||
//
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -19,26 +19,34 @@
|
|||
package glog
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MaxSize is the maximum size of a log file in bytes.
|
||||
var MaxSize uint64 = 1024 * 1024 * 1800
|
||||
"github.com/golang/glog/internal/logsink"
|
||||
)
|
||||
|
||||
// logDirs lists the candidate directories for new log files.
|
||||
var logDirs []string
|
||||
|
||||
// If non-empty, overrides the choice of directory in which to write logs.
|
||||
// See createLogDirs for the full list of possible destinations.
|
||||
var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
|
||||
var (
|
||||
// If non-empty, overrides the choice of directory in which to write logs.
|
||||
// See createLogDirs for the full list of possible destinations.
|
||||
logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
|
||||
logLink = flag.String("log_link", "", "If non-empty, add symbolic links in this directory to the log files")
|
||||
logBufLevel = flag.Int("logbuflevel", int(logsink.Info), "Buffer log messages logged at this level or lower"+
|
||||
" (-1 means don't buffer; 0 means buffer INFO only; ...). Has limited applicability on non-prod platforms.")
|
||||
)
|
||||
|
||||
func createLogDirs() {
|
||||
if *logDir != "" {
|
||||
|
|
@ -64,9 +72,17 @@ func init() {
|
|||
if err == nil {
|
||||
userName = current.Username
|
||||
}
|
||||
|
||||
// Sanitize userName since it may contain filepath separators on Windows.
|
||||
userName = strings.Replace(userName, `\`, "_", -1)
|
||||
// Sanitize userName since it is used to construct file paths.
|
||||
userName = strings.Map(func(r rune) rune {
|
||||
switch {
|
||||
case r >= 'a' && r <= 'z':
|
||||
case r >= 'A' && r <= 'Z':
|
||||
case r >= '0' && r <= '9':
|
||||
default:
|
||||
return '_'
|
||||
}
|
||||
return r
|
||||
}, userName)
|
||||
}
|
||||
|
||||
// shortHostname returns its argument, truncating at the first period.
|
||||
|
|
@ -122,3 +138,270 @@ func create(tag string, t time.Time) (f *os.File, filename string, err error) {
|
|||
}
|
||||
return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
|
||||
}
|
||||
|
||||
// flushSyncWriter is the interface satisfied by logging destinations.
|
||||
type flushSyncWriter interface {
|
||||
Flush() error
|
||||
Sync() error
|
||||
io.Writer
|
||||
filenames() []string
|
||||
}
|
||||
|
||||
var sinks struct {
|
||||
stderr stderrSink
|
||||
file fileSink
|
||||
}
|
||||
|
||||
func init() {
|
||||
sinks.stderr.w = os.Stderr
|
||||
|
||||
// Register stderr first: that way if we crash during file-writing at least
|
||||
// the log will have gone somewhere.
|
||||
logsink.TextSinks = append(logsink.TextSinks, &sinks.stderr, &sinks.file)
|
||||
|
||||
sinks.file.flushChan = make(chan logsink.Severity, 1)
|
||||
go sinks.file.flushDaemon()
|
||||
}
|
||||
|
||||
// stderrSink is a logsink.Text that writes log entries to stderr
|
||||
// if they meet certain conditions.
|
||||
type stderrSink struct {
|
||||
mu sync.Mutex
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// Enabled implements logsink.Text.Enabled. It returns true if any of the
|
||||
// various stderr flags are enabled for logs of the given severity, if the log
|
||||
// message is from the standard "log" package, or if google.Init has not yet run
|
||||
// (and hence file logging is not yet initialized).
|
||||
func (s *stderrSink) Enabled(m *logsink.Meta) bool {
|
||||
return toStderr || alsoToStderr || m.Severity >= stderrThreshold.get()
|
||||
}
|
||||
|
||||
// Emit implements logsink.Text.Emit.
|
||||
func (s *stderrSink) Emit(m *logsink.Meta, data []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
dn, err := s.w.Write(data)
|
||||
n += dn
|
||||
return n, err
|
||||
}
|
||||
|
||||
// severityWriters is an array of flushSyncWriter with a value for each
|
||||
// logsink.Severity.
|
||||
type severityWriters [4]flushSyncWriter
|
||||
|
||||
// fileSink is a logsink.Text that prints to a set of Google log files.
|
||||
type fileSink struct {
|
||||
mu sync.Mutex
|
||||
// file holds writer for each of the log types.
|
||||
file severityWriters
|
||||
flushChan chan logsink.Severity
|
||||
}
|
||||
|
||||
// Enabled implements logsink.Text.Enabled. It returns true if google.Init
|
||||
// has run and both --disable_log_to_disk and --logtostderr are false.
|
||||
func (s *fileSink) Enabled(m *logsink.Meta) bool {
|
||||
return !toStderr
|
||||
}
|
||||
|
||||
// Emit implements logsink.Text.Emit
|
||||
func (s *fileSink) Emit(m *logsink.Meta, data []byte) (n int, err error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if err = s.createMissingFiles(m.Severity); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for sev := m.Severity; sev >= logsink.Info; sev-- {
|
||||
if _, fErr := s.file[sev].Write(data); fErr != nil && err == nil {
|
||||
err = fErr // Take the first error.
|
||||
}
|
||||
}
|
||||
n = len(data)
|
||||
if int(m.Severity) > *logBufLevel {
|
||||
select {
|
||||
case s.flushChan <- m.Severity:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
|
||||
// file's Sync method and providing a wrapper for the Write method that provides log
|
||||
// file rotation. There are conflicting methods, so the file cannot be embedded.
|
||||
// s.mu is held for all its methods.
|
||||
type syncBuffer struct {
|
||||
sink *fileSink
|
||||
*bufio.Writer
|
||||
file *os.File
|
||||
names []string
|
||||
sev logsink.Severity
|
||||
nbytes uint64 // The number of bytes written to this file
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) Sync() error {
|
||||
return sb.file.Sync()
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) Write(p []byte) (n int, err error) {
|
||||
if sb.nbytes+uint64(len(p)) >= MaxSize {
|
||||
if err := sb.rotateFile(time.Now()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
n, err = sb.Writer.Write(p)
|
||||
sb.nbytes += uint64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (sb *syncBuffer) filenames() []string {
|
||||
return sb.names
|
||||
}
|
||||
|
||||
const footer = "\nCONTINUED IN NEXT FILE\n"
|
||||
|
||||
// rotateFile closes the syncBuffer's file and starts a new one.
|
||||
func (sb *syncBuffer) rotateFile(now time.Time) error {
|
||||
var err error
|
||||
pn := "<none>"
|
||||
file, name, err := create(sb.sev.String(), now)
|
||||
|
||||
if sb.file != nil {
|
||||
// The current log file becomes the previous log at the end of
|
||||
// this block, so save its name for use in the header of the next
|
||||
// file.
|
||||
pn = sb.file.Name()
|
||||
sb.Flush()
|
||||
// If there's an existing file, write a footer with the name of
|
||||
// the next file in the chain, followed by the constant string
|
||||
// \nCONTINUED IN NEXT FILE\n to make continuation detection simple.
|
||||
sb.file.Write([]byte("Next log: "))
|
||||
sb.file.Write([]byte(name))
|
||||
sb.file.Write([]byte(footer))
|
||||
sb.file.Close()
|
||||
}
|
||||
|
||||
sb.file = file
|
||||
sb.names = append(sb.names, name)
|
||||
sb.nbytes = 0
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
|
||||
|
||||
// Write header.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
|
||||
fmt.Fprintf(&buf, "Running on machine: %s\n", host)
|
||||
fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||
fmt.Fprintf(&buf, "Previous log: %s\n", pn)
|
||||
fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
|
||||
n, err := sb.file.Write(buf.Bytes())
|
||||
sb.nbytes += uint64(n)
|
||||
return err
|
||||
}
|
||||
|
||||
// bufferSize sizes the buffer associated with each log file. It's large
|
||||
// so that log records can accumulate without the logging thread blocking
|
||||
// on disk I/O. The flushDaemon will block instead.
|
||||
const bufferSize = 256 * 1024
|
||||
|
||||
// createMissingFiles creates all the log files for severity from infoLog up to
|
||||
// upTo that have not already been created.
|
||||
// s.mu is held.
|
||||
func (s *fileSink) createMissingFiles(upTo logsink.Severity) error {
|
||||
if s.file[upTo] != nil {
|
||||
return nil
|
||||
}
|
||||
now := time.Now()
|
||||
// Files are created in increasing severity order, so we can be assured that
|
||||
// if a high severity logfile exists, then so do all of lower severity.
|
||||
for sev := logsink.Info; sev <= upTo; sev++ {
|
||||
if s.file[sev] != nil {
|
||||
continue
|
||||
}
|
||||
sb := &syncBuffer{
|
||||
sink: s,
|
||||
sev: sev,
|
||||
}
|
||||
if err := sb.rotateFile(now); err != nil {
|
||||
return err
|
||||
}
|
||||
s.file[sev] = sb
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// flushDaemon periodically flushes the log file buffers.
|
||||
func (s *fileSink) flushDaemon() {
|
||||
tick := time.NewTicker(30 * time.Second)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
s.Flush()
|
||||
case sev := <-s.flushChan:
|
||||
s.flush(sev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flush flushes all pending log I/O.
|
||||
func Flush() {
|
||||
sinks.file.Flush()
|
||||
}
|
||||
|
||||
// Flush flushes all the logs and attempts to "sync" their data to disk.
|
||||
func (s *fileSink) Flush() error {
|
||||
return s.flush(logsink.Info)
|
||||
}
|
||||
|
||||
// flush flushes all logs of severity threshold or greater.
|
||||
func (s *fileSink) flush(threshold logsink.Severity) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
var firstErr error
|
||||
updateErr := func(err error) {
|
||||
if err != nil && firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
}
|
||||
|
||||
// Flush from fatal down, in case there's trouble flushing.
|
||||
for sev := logsink.Fatal; sev >= threshold; sev-- {
|
||||
file := s.file[sev]
|
||||
if file != nil {
|
||||
updateErr(file.Flush())
|
||||
updateErr(file.Sync())
|
||||
}
|
||||
}
|
||||
|
||||
return firstErr
|
||||
}
|
||||
|
||||
// Names returns the names of the log files holding the FATAL, ERROR,
|
||||
// WARNING, or INFO logs. Returns ErrNoLog if the log for the given
|
||||
// level doesn't exist (e.g. because no messages of that level have been
|
||||
// written). This may return multiple names if the log type requested
|
||||
// has rolled over.
|
||||
func Names(s string) ([]string, error) {
|
||||
severity, err := logsink.ParseSeverity(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sinks.file.mu.Lock()
|
||||
defer sinks.file.mu.Unlock()
|
||||
f := sinks.file.file[severity]
|
||||
if f == nil {
|
||||
return nil, ErrNoLog
|
||||
}
|
||||
|
||||
return f.filenames(), nil
|
||||
}
|
||||
|
|
|
|||
395
vendor/github.com/golang/glog/glog_flags.go
generated
vendored
Normal file
395
vendor/github.com/golang/glog/glog_flags.go
generated
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
// Go support for leveled logs, analogous to https://github.com/google/glog.
|
||||
//
|
||||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 glog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/golang/glog/internal/logsink"
|
||||
)
|
||||
|
||||
// modulePat contains a filter for the -vmodule flag.
|
||||
// It holds a verbosity level and a file pattern to match.
|
||||
type modulePat struct {
|
||||
pattern string
|
||||
literal bool // The pattern is a literal string
|
||||
full bool // The pattern wants to match the full path
|
||||
level Level
|
||||
}
|
||||
|
||||
// match reports whether the file matches the pattern. It uses a string
|
||||
// comparison if the pattern contains no metacharacters.
|
||||
func (m *modulePat) match(full, file string) bool {
|
||||
if m.literal {
|
||||
if m.full {
|
||||
return full == m.pattern
|
||||
}
|
||||
return file == m.pattern
|
||||
}
|
||||
if m.full {
|
||||
match, _ := filepath.Match(m.pattern, full)
|
||||
return match
|
||||
}
|
||||
match, _ := filepath.Match(m.pattern, file)
|
||||
return match
|
||||
}
|
||||
|
||||
// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
|
||||
// that require filepath.Match to be called to match the pattern.
|
||||
func isLiteral(pattern string) bool {
|
||||
return !strings.ContainsAny(pattern, `\*?[]`)
|
||||
}
|
||||
|
||||
// isFull reports whether the pattern matches the full file path, that is,
|
||||
// whether it contains /.
|
||||
func isFull(pattern string) bool {
|
||||
return strings.ContainsRune(pattern, '/')
|
||||
}
|
||||
|
||||
// verboseFlags represents the setting of the -v and -vmodule flags.
|
||||
type verboseFlags struct {
|
||||
// moduleLevelCache is a sync.Map storing the -vmodule Level for each V()
|
||||
// call site, identified by PC. If there is no matching -vmodule filter,
|
||||
// the cached value is exactly v. moduleLevelCache is replaced with a new
|
||||
// Map whenever the -vmodule or -v flag changes state.
|
||||
moduleLevelCache atomic.Value
|
||||
|
||||
// mu guards all fields below.
|
||||
mu sync.Mutex
|
||||
|
||||
// v stores the value of the -v flag. It may be read safely using
|
||||
// sync.LoadInt32, but is only modified under mu.
|
||||
v Level
|
||||
|
||||
// module stores the parsed -vmodule flag.
|
||||
module []modulePat
|
||||
|
||||
// moduleLength caches len(module). If greater than zero, it
|
||||
// means vmodule is enabled. It may be read safely using sync.LoadInt32, but
|
||||
// is only modified under mu.
|
||||
moduleLength int32
|
||||
}
|
||||
|
||||
// NOTE: For compatibility with the open-sourced v1 version of this
|
||||
// package (github.com/golang/glog) we need to retain that flag.Level
|
||||
// implements the flag.Value interface. See also go/log-vs-glog.
|
||||
|
||||
// String is part of the flag.Value interface.
|
||||
func (l *Level) String() string {
|
||||
return strconv.FormatInt(int64(l.Get().(Level)), 10)
|
||||
}
|
||||
|
||||
// Get is part of the flag.Value interface.
|
||||
func (l *Level) Get() any {
|
||||
if l == &vflags.v {
|
||||
// l is the value registered for the -v flag.
|
||||
return Level(atomic.LoadInt32((*int32)(l)))
|
||||
}
|
||||
return *l
|
||||
}
|
||||
|
||||
// Set is part of the flag.Value interface.
|
||||
func (l *Level) Set(value string) error {
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if l == &vflags.v {
|
||||
// l is the value registered for the -v flag.
|
||||
vflags.mu.Lock()
|
||||
defer vflags.mu.Unlock()
|
||||
vflags.moduleLevelCache.Store(&sync.Map{})
|
||||
atomic.StoreInt32((*int32)(l), int32(v))
|
||||
return nil
|
||||
}
|
||||
*l = Level(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// vModuleFlag is the flag.Value for the --vmodule flag.
|
||||
type vModuleFlag struct{ *verboseFlags }
|
||||
|
||||
func (f vModuleFlag) String() string {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
var b bytes.Buffer
|
||||
for i, f := range f.module {
|
||||
if i > 0 {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Get returns nil for this flag type since the struct is not exported.
|
||||
func (f vModuleFlag) Get() any { return nil }
|
||||
|
||||
var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
|
||||
// Syntax: -vmodule=recordio=2,foo/bar/baz=1,gfs*=3
|
||||
func (f vModuleFlag) Set(value string) error {
|
||||
var filter []modulePat
|
||||
for _, pat := range strings.Split(value, ",") {
|
||||
if len(pat) == 0 {
|
||||
// Empty strings such as from a trailing comma can be ignored.
|
||||
continue
|
||||
}
|
||||
patLev := strings.Split(pat, "=")
|
||||
if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
|
||||
return errVmoduleSyntax
|
||||
}
|
||||
pattern := patLev[0]
|
||||
v, err := strconv.Atoi(patLev[1])
|
||||
if err != nil {
|
||||
return errors.New("syntax error: expect comma-separated list of filename=N")
|
||||
}
|
||||
// TODO: check syntax of filter?
|
||||
filter = append(filter, modulePat{pattern, isLiteral(pattern), isFull(pattern), Level(v)})
|
||||
}
|
||||
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
f.module = filter
|
||||
atomic.StoreInt32((*int32)(&f.moduleLength), int32(len(f.module)))
|
||||
f.moduleLevelCache.Store(&sync.Map{})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *verboseFlags) levelForPC(pc uintptr) Level {
|
||||
if level, ok := f.moduleLevelCache.Load().(*sync.Map).Load(pc); ok {
|
||||
return level.(Level)
|
||||
}
|
||||
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
level := Level(f.v)
|
||||
fn := runtime.FuncForPC(pc)
|
||||
file, _ := fn.FileLine(pc)
|
||||
// The file is something like /a/b/c/d.go. We want just the d for
|
||||
// regular matches, /a/b/c/d for full matches.
|
||||
if strings.HasSuffix(file, ".go") {
|
||||
file = file[:len(file)-3]
|
||||
}
|
||||
full := file
|
||||
if slash := strings.LastIndex(file, "/"); slash >= 0 {
|
||||
file = file[slash+1:]
|
||||
}
|
||||
for _, filter := range f.module {
|
||||
if filter.match(full, file) {
|
||||
level = filter.level
|
||||
break // Use the first matching level.
|
||||
}
|
||||
}
|
||||
f.moduleLevelCache.Load().(*sync.Map).Store(pc, level)
|
||||
return level
|
||||
}
|
||||
|
||||
func (f *verboseFlags) enabled(callerDepth int, level Level) bool {
|
||||
if atomic.LoadInt32(&f.moduleLength) == 0 {
|
||||
// No vmodule values specified, so compare against v level.
|
||||
return Level(atomic.LoadInt32((*int32)(&f.v))) >= level
|
||||
}
|
||||
|
||||
pcs := [1]uintptr{}
|
||||
if runtime.Callers(callerDepth+2, pcs[:]) < 1 {
|
||||
return false
|
||||
}
|
||||
frame, _ := runtime.CallersFrames(pcs[:]).Next()
|
||||
return f.levelForPC(frame.Entry) >= level
|
||||
}
|
||||
|
||||
// traceLocation represents an entry in the -log_backtrace_at flag.
|
||||
type traceLocation struct {
|
||||
file string
|
||||
line int
|
||||
}
|
||||
|
||||
var errTraceSyntax = errors.New("syntax error: expect file.go:234")
|
||||
|
||||
func parseTraceLocation(value string) (traceLocation, error) {
|
||||
fields := strings.Split(value, ":")
|
||||
if len(fields) != 2 {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
file, lineStr := fields[0], fields[1]
|
||||
if !strings.Contains(file, ".") {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
line, err := strconv.Atoi(lineStr)
|
||||
if err != nil {
|
||||
return traceLocation{}, errTraceSyntax
|
||||
}
|
||||
if line < 0 {
|
||||
return traceLocation{}, errors.New("negative value for line")
|
||||
}
|
||||
return traceLocation{file, line}, nil
|
||||
}
|
||||
|
||||
// match reports whether the specified file and line matches the trace location.
|
||||
// The argument file name is the full path, not the basename specified in the flag.
|
||||
func (t traceLocation) match(file string, line int) bool {
|
||||
if t.line != line {
|
||||
return false
|
||||
}
|
||||
if i := strings.LastIndex(file, "/"); i >= 0 {
|
||||
file = file[i+1:]
|
||||
}
|
||||
return t.file == file
|
||||
}
|
||||
|
||||
func (t traceLocation) String() string {
|
||||
return fmt.Sprintf("%s:%d", t.file, t.line)
|
||||
}
|
||||
|
||||
// traceLocations represents the -log_backtrace_at flag.
|
||||
// Syntax: -log_backtrace_at=recordio.go:234,sstable.go:456
|
||||
// Note that unlike vmodule the file extension is included here.
|
||||
type traceLocations struct {
|
||||
mu sync.Mutex
|
||||
locsLen int32 // Safe for atomic read without mu.
|
||||
locs []traceLocation
|
||||
}
|
||||
|
||||
func (t *traceLocations) String() string {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
var buf bytes.Buffer
|
||||
for i, tl := range t.locs {
|
||||
if i > 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
buf.WriteString(tl.String())
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Get always returns nil for this flag type since the struct is not exported
|
||||
func (t *traceLocations) Get() any { return nil }
|
||||
|
||||
func (t *traceLocations) Set(value string) error {
|
||||
var locs []traceLocation
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
loc, err := parseTraceLocation(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
locs = append(locs, loc)
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
atomic.StoreInt32(&t.locsLen, int32(len(locs)))
|
||||
t.locs = locs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *traceLocations) match(file string, line int) bool {
|
||||
if atomic.LoadInt32(&t.locsLen) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
for _, tl := range t.locs {
|
||||
if tl.match(file, line) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// severityFlag is an atomic flag.Value implementation for logsink.Severity.
|
||||
type severityFlag int32
|
||||
|
||||
func (s *severityFlag) get() logsink.Severity {
|
||||
return logsink.Severity(atomic.LoadInt32((*int32)(s)))
|
||||
}
|
||||
func (s *severityFlag) String() string { return strconv.FormatInt(int64(*s), 10) }
|
||||
func (s *severityFlag) Get() any { return s.get() }
|
||||
func (s *severityFlag) Set(value string) error {
|
||||
threshold, err := logsink.ParseSeverity(value)
|
||||
if err != nil {
|
||||
// Not a severity name. Try a raw number.
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
threshold = logsink.Severity(v)
|
||||
if threshold < logsink.Info || threshold > logsink.Fatal {
|
||||
return fmt.Errorf("Severity %d out of range (min %d, max %d).", v, logsink.Info, logsink.Fatal)
|
||||
}
|
||||
}
|
||||
atomic.StoreInt32((*int32)(s), int32(threshold))
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
vflags verboseFlags // The -v and -vmodule flags.
|
||||
|
||||
logBacktraceAt traceLocations // The -log_backtrace_at flag.
|
||||
|
||||
// Boolean flags. Not handled atomically because the flag.Value interface
|
||||
// does not let us avoid the =true, and that shorthand is necessary for
|
||||
// compatibility. TODO: does this matter enough to fix? Seems unlikely.
|
||||
toStderr bool // The -logtostderr flag.
|
||||
alsoToStderr bool // The -alsologtostderr flag.
|
||||
|
||||
stderrThreshold severityFlag // The -stderrthreshold flag.
|
||||
)
|
||||
|
||||
// verboseEnabled returns whether the caller at the given depth should emit
|
||||
// verbose logs at the given level, with depth 0 identifying the caller of
|
||||
// verboseEnabled.
|
||||
func verboseEnabled(callerDepth int, level Level) bool {
|
||||
return vflags.enabled(callerDepth+1, level)
|
||||
}
|
||||
|
||||
// backtraceAt returns whether the logging call at the given function and line
|
||||
// should also emit a backtrace of the current call stack.
|
||||
func backtraceAt(file string, line int) bool {
|
||||
return logBacktraceAt.match(file, line)
|
||||
}
|
||||
|
||||
func init() {
|
||||
vflags.moduleLevelCache.Store(&sync.Map{})
|
||||
|
||||
flag.Var(&vflags.v, "v", "log level for V logs")
|
||||
flag.Var(vModuleFlag{&vflags}, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
|
||||
|
||||
flag.Var(&logBacktraceAt, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
|
||||
|
||||
stderrThreshold = severityFlag(logsink.Error)
|
||||
|
||||
flag.BoolVar(&toStderr, "logtostderr", false, "log to standard error instead of files")
|
||||
flag.BoolVar(&alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
|
||||
flag.Var(&stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
|
||||
}
|
||||
387
vendor/github.com/golang/glog/internal/logsink/logsink.go
generated
vendored
Normal file
387
vendor/github.com/golang/glog/internal/logsink/logsink.go
generated
vendored
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 logsink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog/internal/stackdump"
|
||||
)
|
||||
|
||||
// MaxLogMessageLen is the limit on length of a formatted log message, including
|
||||
// the standard line prefix and trailing newline.
|
||||
//
|
||||
// Chosen to match C++ glog.
|
||||
const MaxLogMessageLen = 15000
|
||||
|
||||
// A Severity is a severity at which a message can be logged.
|
||||
type Severity int8
|
||||
|
||||
// These constants identify the log levels in order of increasing severity.
|
||||
// A message written to a high-severity log file is also written to each
|
||||
// lower-severity log file.
|
||||
const (
|
||||
Info Severity = iota
|
||||
Warning
|
||||
Error
|
||||
|
||||
// Fatal contains logs written immediately before the process terminates.
|
||||
//
|
||||
// Sink implementations should not terminate the process themselves: the log
|
||||
// package will perform any necessary cleanup and terminate the process as
|
||||
// appropriate.
|
||||
Fatal
|
||||
)
|
||||
|
||||
func (s Severity) String() string {
|
||||
switch s {
|
||||
case Info:
|
||||
return "INFO"
|
||||
case Warning:
|
||||
return "WARNING"
|
||||
case Error:
|
||||
return "ERROR"
|
||||
case Fatal:
|
||||
return "FATAL"
|
||||
}
|
||||
return fmt.Sprintf("%T(%d)", s, s)
|
||||
}
|
||||
|
||||
// ParseSeverity returns the case-insensitive Severity value for the given string.
|
||||
func ParseSeverity(name string) (Severity, error) {
|
||||
name = strings.ToUpper(name)
|
||||
for s := Info; s <= Fatal; s++ {
|
||||
if s.String() == name {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("logsink: invalid severity %q", name)
|
||||
}
|
||||
|
||||
// Meta is metadata about a logging call.
|
||||
type Meta struct {
|
||||
// Time is the time at which the log call was made.
|
||||
Time time.Time
|
||||
|
||||
// File is the source file from which the log entry originates.
|
||||
File string
|
||||
// Line is the line offset within the source file.
|
||||
Line int
|
||||
// Depth is the number of stack frames between the logsink and the log call.
|
||||
Depth int
|
||||
|
||||
Severity Severity
|
||||
|
||||
// Verbose indicates whether the call was made via "log.V". Log entries below
|
||||
// the current verbosity threshold are not sent to the sink.
|
||||
Verbose bool
|
||||
|
||||
// Thread ID. This can be populated with a thread ID from another source,
|
||||
// such as a system we are importing logs from. In the normal case, this
|
||||
// will be set to the process ID (PID), since Go doesn't have threads.
|
||||
Thread int64
|
||||
|
||||
// Stack trace starting in the logging function. May be nil.
|
||||
// A logsink should implement the StackWanter interface to request this.
|
||||
//
|
||||
// Even if WantStack returns false, this field may be set (e.g. if another
|
||||
// sink wants a stack trace).
|
||||
Stack *stackdump.Stack
|
||||
}
|
||||
|
||||
// Structured is a logging destination that accepts structured data as input.
|
||||
type Structured interface {
|
||||
// Printf formats according to a fmt.Printf format specifier and writes a log
|
||||
// entry. The precise result of formatting depends on the sink, but should
|
||||
// aim for consistency with fmt.Printf.
|
||||
//
|
||||
// Printf returns the number of bytes occupied by the log entry, which
|
||||
// may not be equal to the total number of bytes written.
|
||||
//
|
||||
// Printf returns any error encountered *if* it is severe enough that the log
|
||||
// package should terminate the process.
|
||||
//
|
||||
// The sink must not modify the *Meta parameter, nor reference it after
|
||||
// Printf has returned: it may be reused in subsequent calls.
|
||||
Printf(meta *Meta, format string, a ...any) (n int, err error)
|
||||
}
|
||||
|
||||
// StackWanter can be implemented by a logsink.Structured to indicate that it
|
||||
// wants a stack trace to accompany at least some of the log messages it receives.
|
||||
type StackWanter interface {
|
||||
// WantStack returns true if the sink requires a stack trace for a log message
|
||||
// with this metadata.
|
||||
//
|
||||
// NOTE: Returning true implies that meta.Stack will be non-nil. Returning
|
||||
// false does NOT imply that meta.Stack will be nil.
|
||||
WantStack(meta *Meta) bool
|
||||
}
|
||||
|
||||
// Text is a logging destination that accepts pre-formatted log lines (instead of
|
||||
// structured data).
|
||||
type Text interface {
|
||||
// Enabled returns whether this sink should output messages for the given
|
||||
// Meta. If the sink returns false for a given Meta, the Printf function will
|
||||
// not call Emit on it for the corresponding log message.
|
||||
Enabled(*Meta) bool
|
||||
|
||||
// Emit writes a pre-formatted text log entry (including any applicable
|
||||
// header) to the log. It returns the number of bytes occupied by the entry
|
||||
// (which may differ from the length of the passed-in slice).
|
||||
//
|
||||
// Emit returns any error encountered *if* it is severe enough that the log
|
||||
// package should terminate the process.
|
||||
//
|
||||
// The sink must not modify the *Meta parameter, nor reference it after
|
||||
// Printf has returned: it may be reused in subsequent calls.
|
||||
//
|
||||
// NOTE: When developing a text sink, keep in mind the surface in which the
|
||||
// logs will be displayed, and whether it's important that the sink be
|
||||
// resistent to tampering in the style of b/211428300. Standard text sinks
|
||||
// (like `stderrSink`) do not protect against this (e.g. by escaping
|
||||
// characters) because the cases where they would show user-influenced bytes
|
||||
// are vanishingly small.
|
||||
Emit(*Meta, []byte) (n int, err error)
|
||||
}
|
||||
|
||||
// bufs is a pool of *bytes.Buffer used in formatting log entries.
|
||||
var bufs sync.Pool // Pool of *bytes.Buffer.
|
||||
|
||||
// textPrintf formats a text log entry and emits it to all specified Text sinks.
|
||||
//
|
||||
// The returned n is the maximum across all Emit calls.
|
||||
// The returned err is the first non-nil error encountered.
|
||||
// Sinks that are disabled by configuration should return (0, nil).
|
||||
func textPrintf(m *Meta, textSinks []Text, format string, args ...any) (n int, err error) {
|
||||
// We expect at most file, stderr, and perhaps syslog. If there are more,
|
||||
// we'll end up allocating - no big deal.
|
||||
const maxExpectedTextSinks = 3
|
||||
var noAllocSinks [maxExpectedTextSinks]Text
|
||||
|
||||
sinks := noAllocSinks[:0]
|
||||
for _, s := range textSinks {
|
||||
if s.Enabled(m) {
|
||||
sinks = append(sinks, s)
|
||||
}
|
||||
}
|
||||
if len(sinks) == 0 && m.Severity != Fatal {
|
||||
return 0, nil // No TextSinks specified; don't bother formatting.
|
||||
}
|
||||
|
||||
bufi := bufs.Get()
|
||||
var buf *bytes.Buffer
|
||||
if bufi == nil {
|
||||
buf = bytes.NewBuffer(nil)
|
||||
bufi = buf
|
||||
} else {
|
||||
buf = bufi.(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
}
|
||||
|
||||
// Lmmdd hh:mm:ss.uuuuuu PID/GID file:line]
|
||||
//
|
||||
// The "PID" entry arguably ought to be TID for consistency with other
|
||||
// environments, but TID is not meaningful in a Go program due to the
|
||||
// multiplexing of goroutines across threads.
|
||||
//
|
||||
// Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
|
||||
// It's worth about 3X. Fprintf is hard.
|
||||
const severityChar = "IWEF"
|
||||
buf.WriteByte(severityChar[m.Severity])
|
||||
|
||||
_, month, day := m.Time.Date()
|
||||
hour, minute, second := m.Time.Clock()
|
||||
twoDigits(buf, int(month))
|
||||
twoDigits(buf, day)
|
||||
buf.WriteByte(' ')
|
||||
twoDigits(buf, hour)
|
||||
buf.WriteByte(':')
|
||||
twoDigits(buf, minute)
|
||||
buf.WriteByte(':')
|
||||
twoDigits(buf, second)
|
||||
buf.WriteByte('.')
|
||||
nDigits(buf, 6, uint64(m.Time.Nanosecond()/1000), '0')
|
||||
buf.WriteByte(' ')
|
||||
|
||||
nDigits(buf, 7, uint64(m.Thread), ' ')
|
||||
buf.WriteByte(' ')
|
||||
|
||||
{
|
||||
file := m.File
|
||||
if i := strings.LastIndex(file, "/"); i >= 0 {
|
||||
file = file[i+1:]
|
||||
}
|
||||
buf.WriteString(file)
|
||||
}
|
||||
|
||||
buf.WriteByte(':')
|
||||
{
|
||||
var tmp [19]byte
|
||||
buf.Write(strconv.AppendInt(tmp[:0], int64(m.Line), 10))
|
||||
}
|
||||
buf.WriteString("] ")
|
||||
|
||||
msgStart := buf.Len()
|
||||
fmt.Fprintf(buf, format, args...)
|
||||
if buf.Len() > MaxLogMessageLen-1 {
|
||||
buf.Truncate(MaxLogMessageLen - 1)
|
||||
}
|
||||
msgEnd := buf.Len()
|
||||
if b := buf.Bytes(); b[len(b)-1] != '\n' {
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
|
||||
for _, s := range sinks {
|
||||
sn, sErr := s.Emit(m, buf.Bytes())
|
||||
if sn > n {
|
||||
n = sn
|
||||
}
|
||||
if sErr != nil && err == nil {
|
||||
err = sErr
|
||||
}
|
||||
}
|
||||
|
||||
if m.Severity == Fatal {
|
||||
savedM := *m
|
||||
fatalMessageStore(savedEntry{
|
||||
meta: &savedM,
|
||||
msg: buf.Bytes()[msgStart:msgEnd],
|
||||
})
|
||||
} else {
|
||||
bufs.Put(bufi)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
const digits = "0123456789"
|
||||
|
||||
// twoDigits formats a zero-prefixed two-digit integer to buf.
|
||||
func twoDigits(buf *bytes.Buffer, d int) {
|
||||
buf.WriteByte(digits[(d/10)%10])
|
||||
buf.WriteByte(digits[d%10])
|
||||
}
|
||||
|
||||
// nDigits formats an n-digit integer to buf, padding with pad on the left. It
|
||||
// assumes d != 0.
|
||||
func nDigits(buf *bytes.Buffer, n int, d uint64, pad byte) {
|
||||
var tmp [20]byte
|
||||
|
||||
cutoff := len(tmp) - n
|
||||
j := len(tmp) - 1
|
||||
for ; d > 0; j-- {
|
||||
tmp[j] = digits[d%10]
|
||||
d /= 10
|
||||
}
|
||||
for ; j >= cutoff; j-- {
|
||||
tmp[j] = pad
|
||||
}
|
||||
j++
|
||||
buf.Write(tmp[j:])
|
||||
}
|
||||
|
||||
// Printf writes a log entry to all registered TextSinks in this package, then
|
||||
// to all registered StructuredSinks.
|
||||
//
|
||||
// The returned n is the maximum across all Emit and Printf calls.
|
||||
// The returned err is the first non-nil error encountered.
|
||||
// Sinks that are disabled by configuration should return (0, nil).
|
||||
func Printf(m *Meta, format string, args ...any) (n int, err error) {
|
||||
m.Depth++
|
||||
n, err = textPrintf(m, TextSinks, format, args...)
|
||||
|
||||
for _, sink := range StructuredSinks {
|
||||
// TODO: Support TextSinks that implement StackWanter?
|
||||
if sw, ok := sink.(StackWanter); ok && sw.WantStack(m) {
|
||||
if m.Stack == nil {
|
||||
// First, try to find a stacktrace in args, otherwise generate one.
|
||||
for _, arg := range args {
|
||||
if stack, ok := arg.(stackdump.Stack); ok {
|
||||
m.Stack = &stack
|
||||
break
|
||||
}
|
||||
}
|
||||
if m.Stack == nil {
|
||||
stack := stackdump.Caller( /* skipDepth = */ m.Depth)
|
||||
m.Stack = &stack
|
||||
}
|
||||
}
|
||||
}
|
||||
sn, sErr := sink.Printf(m, format, args...)
|
||||
if sn > n {
|
||||
n = sn
|
||||
}
|
||||
if sErr != nil && err == nil {
|
||||
err = sErr
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// The sets of sinks to which logs should be written.
|
||||
//
|
||||
// These must only be modified during package init, and are read-only thereafter.
|
||||
var (
|
||||
// StructuredSinks is the set of Structured sink instances to which logs
|
||||
// should be written.
|
||||
StructuredSinks []Structured
|
||||
|
||||
// TextSinks is the set of Text sink instances to which logs should be
|
||||
// written.
|
||||
//
|
||||
// These are registered separately from Structured sink implementations to
|
||||
// avoid the need to repeat the work of formatting a message for each Text
|
||||
// sink that writes it. The package-level Printf function writes to both sets
|
||||
// independenty, so a given log destination should only register a Structured
|
||||
// *or* a Text sink (not both).
|
||||
TextSinks []Text
|
||||
)
|
||||
|
||||
type savedEntry struct {
|
||||
meta *Meta
|
||||
msg []byte
|
||||
}
|
||||
|
||||
// StructuredTextWrapper is a Structured sink which forwards logs to a set of Text sinks.
|
||||
//
|
||||
// The purpose of this sink is to allow applications to intercept logging calls before they are
|
||||
// serialized and sent to Text sinks. For example, if one needs to redact PII from logging
|
||||
// arguments before they reach STDERR, one solution would be to do the redacting in a Structured
|
||||
// sink that forwards logs to a StructuredTextWrapper instance, and make STDERR a child of that
|
||||
// StructuredTextWrapper instance. This is how one could set this up in their application:
|
||||
//
|
||||
// func init() {
|
||||
//
|
||||
// wrapper := logsink.StructuredTextWrapper{TextSinks: logsink.TextSinks}
|
||||
// // sanitizersink will intercept logs and remove PII
|
||||
// sanitizer := sanitizersink{Sink: &wrapper}
|
||||
// logsink.StructuredSinks = append(logsink.StructuredSinks, &sanitizer)
|
||||
// logsink.TextSinks = nil
|
||||
//
|
||||
// }
|
||||
type StructuredTextWrapper struct {
|
||||
// TextSinks is the set of Text sinks that should receive logs from this
|
||||
// StructuredTextWrapper instance.
|
||||
TextSinks []Text
|
||||
}
|
||||
|
||||
// Printf forwards logs to all Text sinks registered in the StructuredTextWrapper.
|
||||
func (w *StructuredTextWrapper) Printf(meta *Meta, format string, args ...any) (n int, err error) {
|
||||
return textPrintf(meta, w.TextSinks, format, args...)
|
||||
}
|
||||
35
vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go
generated
vendored
Normal file
35
vendor/github.com/golang/glog/internal/logsink/logsink_fatal.go
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package logsink
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func fatalMessageStore(e savedEntry) {
|
||||
// Only put a new one in if we haven't assigned before.
|
||||
atomic.CompareAndSwapPointer(&fatalMessage, nil, unsafe.Pointer(&e))
|
||||
}
|
||||
|
||||
var fatalMessage unsafe.Pointer // savedEntry stored with CompareAndSwapPointer
|
||||
|
||||
// FatalMessage returns the Meta and message contents of the first message
|
||||
// logged with Fatal severity, or false if none has occurred.
|
||||
func FatalMessage() (*Meta, []byte, bool) {
|
||||
e := (*savedEntry)(atomic.LoadPointer(&fatalMessage))
|
||||
if e == nil {
|
||||
return nil, nil, false
|
||||
}
|
||||
return e.meta, e.msg, true
|
||||
}
|
||||
|
||||
// DoNotUseRacyFatalMessage is FatalMessage, but worse.
|
||||
//
|
||||
//go:norace
|
||||
//go:nosplit
|
||||
func DoNotUseRacyFatalMessage() (*Meta, []byte, bool) {
|
||||
e := (*savedEntry)(fatalMessage)
|
||||
if e == nil {
|
||||
return nil, nil, false
|
||||
}
|
||||
return e.meta, e.msg, true
|
||||
}
|
||||
127
vendor/github.com/golang/glog/internal/stackdump/stackdump.go
generated
vendored
Normal file
127
vendor/github.com/golang/glog/internal/stackdump/stackdump.go
generated
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2023 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 stackdump provides wrappers for runtime.Stack and runtime.Callers
|
||||
// with uniform support for skipping caller frames.
|
||||
//
|
||||
// ⚠ Unlike the functions in the runtime package, these may allocate a
|
||||
// non-trivial quantity of memory: use them with care. ⚠
|
||||
package stackdump
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// runtimeStackSelfFrames is 1 if runtime.Stack includes the call to
|
||||
// runtime.Stack itself or 0 if it does not.
|
||||
//
|
||||
// As of 2016-04-27, the gccgo compiler includes runtime.Stack but the gc
|
||||
// compiler does not.
|
||||
var runtimeStackSelfFrames = func() int {
|
||||
for n := 1 << 10; n < 1<<20; n *= 2 {
|
||||
buf := make([]byte, n)
|
||||
n := runtime.Stack(buf, false)
|
||||
if bytes.Contains(buf[:n], []byte("runtime.Stack")) {
|
||||
return 1
|
||||
} else if n < len(buf) || bytes.Count(buf, []byte("\n")) >= 3 {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}()
|
||||
|
||||
// Stack is a stack dump for a single goroutine.
|
||||
type Stack struct {
|
||||
// Text is a representation of the stack dump in a human-readable format.
|
||||
Text []byte
|
||||
|
||||
// PC is a representation of the stack dump using raw program counter values.
|
||||
PC []uintptr
|
||||
}
|
||||
|
||||
func (s Stack) String() string { return string(s.Text) }
|
||||
|
||||
// Caller returns the Stack dump for the calling goroutine, starting skipDepth
|
||||
// frames before the caller of Caller. (Caller(0) provides a dump starting at
|
||||
// the caller of this function.)
|
||||
func Caller(skipDepth int) Stack {
|
||||
return Stack{
|
||||
Text: CallerText(skipDepth + 1),
|
||||
PC: CallerPC(skipDepth + 1),
|
||||
}
|
||||
}
|
||||
|
||||
// CallerText returns a textual dump of the stack starting skipDepth frames before
|
||||
// the caller. (CallerText(0) provides a dump starting at the caller of this
|
||||
// function.)
|
||||
func CallerText(skipDepth int) []byte {
|
||||
for n := 1 << 10; ; n *= 2 {
|
||||
buf := make([]byte, n)
|
||||
n := runtime.Stack(buf, false)
|
||||
if n < len(buf) {
|
||||
return pruneFrames(skipDepth+1+runtimeStackSelfFrames, buf[:n])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CallerPC returns a dump of the program counters of the stack starting
|
||||
// skipDepth frames before the caller. (CallerPC(0) provides a dump starting at
|
||||
// the caller of this function.)
|
||||
func CallerPC(skipDepth int) []uintptr {
|
||||
for n := 1 << 8; ; n *= 2 {
|
||||
buf := make([]uintptr, n)
|
||||
n := runtime.Callers(skipDepth+2, buf)
|
||||
if n < len(buf) {
|
||||
return buf[:n]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pruneFrames removes the topmost skipDepth frames of the first goroutine in a
|
||||
// textual stack dump. It overwrites the passed-in slice.
|
||||
//
|
||||
// If there are fewer than skipDepth frames in the first goroutine's stack,
|
||||
// pruneFrames prunes it to an empty stack and leaves the remaining contents
|
||||
// intact.
|
||||
func pruneFrames(skipDepth int, stack []byte) []byte {
|
||||
headerLen := 0
|
||||
for i, c := range stack {
|
||||
if c == '\n' {
|
||||
headerLen = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if headerLen == 0 {
|
||||
return stack // No header line - not a well-formed stack trace.
|
||||
}
|
||||
|
||||
skipLen := headerLen
|
||||
skipNewlines := skipDepth * 2
|
||||
for ; skipLen < len(stack) && skipNewlines > 0; skipLen++ {
|
||||
c := stack[skipLen]
|
||||
if c != '\n' {
|
||||
continue
|
||||
}
|
||||
skipNewlines--
|
||||
skipLen++
|
||||
if skipNewlines == 0 || skipLen == len(stack) || stack[skipLen] == '\n' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
pruned := stack[skipLen-headerLen:]
|
||||
copy(pruned, stack[:headerLen])
|
||||
return pruned
|
||||
}
|
||||
8
vendor/github.com/golang/protobuf/jsonpb/decode.go
generated
vendored
8
vendor/github.com/golang/protobuf/jsonpb/decode.go
generated
vendored
|
|
@ -386,8 +386,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
|
|||
}
|
||||
|
||||
func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
|
||||
if fd.Cardinality() == protoreflect.Repeated {
|
||||
return false
|
||||
}
|
||||
if md := fd.Message(); md != nil {
|
||||
return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
|
||||
return md.FullName() == "google.protobuf.Value"
|
||||
}
|
||||
if ed := fd.Enum(); ed != nil {
|
||||
return ed.FullName() == "google.protobuf.NullValue"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
62
vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/empty/empty.proto
|
||||
|
||||
package empty
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// Symbols defined in public import of google/protobuf/empty.proto.
|
||||
|
||||
type Empty = emptypb.Empty
|
||||
|
||||
var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{
|
||||
0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
|
||||
0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{}
|
||||
var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() }
|
||||
func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() {
|
||||
if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs,
|
||||
}.Build()
|
||||
File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil
|
||||
file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil
|
||||
}
|
||||
6
vendor/github.com/google/s2a-go/.gitignore
generated
vendored
Normal file
6
vendor/github.com/google/s2a-go/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Ignore binaries without extension
|
||||
//example/client/client
|
||||
//example/server/server
|
||||
//internal/v2/fakes2av2_server/fakes2av2_server
|
||||
|
||||
.idea/
|
||||
93
vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md
generated
vendored
Normal file
93
vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md
generated
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of
|
||||
experience, education, socio-economic status, nationality, personal appearance,
|
||||
race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, or to ban temporarily or permanently any
|
||||
contributor for other behaviors that they deem inappropriate, threatening,
|
||||
offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
This Code of Conduct also applies outside the project spaces when the Project
|
||||
Steward has a reasonable belief that an individual's behavior may have a
|
||||
negative impact on the project or its community.
|
||||
|
||||
## Conflict Resolution
|
||||
|
||||
We do not believe that all conflict is bad; healthy debate and disagreement
|
||||
often yield positive results. However, it is never okay to be disrespectful or
|
||||
to engage in behavior that violates the project’s code of conduct.
|
||||
|
||||
If you see someone violating the code of conduct, you are encouraged to address
|
||||
the behavior directly with those involved. Many issues can be resolved quickly
|
||||
and easily, and this gives people more control over the outcome of their
|
||||
dispute. If you are unable to resolve the matter for any reason, or if the
|
||||
behavior is threatening or harassing, report it. We are dedicated to providing
|
||||
an environment where participants feel welcome and safe.
|
||||
|
||||
Reports should be directed to *[PROJECT STEWARD NAME(s) AND EMAIL(s)]*, the
|
||||
Project Steward(s) for *[PROJECT NAME]*. It is the Project Steward’s duty to
|
||||
receive and address reported violations of the code of conduct. They will then
|
||||
work with a committee consisting of representatives from the Open Source
|
||||
Programs Office and the Google Open Source Strategy team. If for any reason you
|
||||
are uncomfortable reaching out to the Project Steward, please email
|
||||
opensource@google.com.
|
||||
|
||||
We will investigate every complaint, but you may not receive a direct response.
|
||||
We will use our discretion in determining when and how to follow up on reported
|
||||
incidents, which may range from not taking action to permanent expulsion from
|
||||
the project and project-sponsored spaces. We will notify the accused of the
|
||||
report and provide them an opportunity to discuss it before any action is taken.
|
||||
The identity of the reporter will be omitted from the details of the report
|
||||
supplied to the accused. In potentially harmful situations, such as ongoing
|
||||
harassment or threats to anyone's safety, we may take action without notice.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
|
||||
available at
|
||||
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
29
vendor/github.com/google/s2a-go/CONTRIBUTING.md
generated
vendored
Normal file
29
vendor/github.com/google/s2a-go/CONTRIBUTING.md
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# How to Contribute
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Contributions to this project must be accompanied by a Contributor License
|
||||
Agreement (CLA). You (or your employer) retain the copyright to your
|
||||
contribution; this simply gives us permission to use and redistribute your
|
||||
contributions as part of the project. Head over to
|
||||
<https://cla.developers.google.com/> to see your current agreements on file or
|
||||
to sign a new one.
|
||||
|
||||
You generally only need to submit a CLA once, so if you've already submitted one
|
||||
(even if it was for a different project), you probably don't need to do it
|
||||
again.
|
||||
|
||||
## Code reviews
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use GitHub pull requests for this purpose. Consult
|
||||
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||
information on using pull requests.
|
||||
|
||||
## Community Guidelines
|
||||
|
||||
This project follows
|
||||
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
|
||||
202
vendor/github.com/google/s2a-go/LICENSE.md
generated
vendored
Normal file
202
vendor/github.com/google/s2a-go/LICENSE.md
generated
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
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.
|
||||
17
vendor/github.com/google/s2a-go/README.md
generated
vendored
Normal file
17
vendor/github.com/google/s2a-go/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Secure Session Agent Client Libraries
|
||||
|
||||
The Secure Session Agent is a service that enables a workload to offload select
|
||||
operations from the mTLS handshake and protects a workload's private key
|
||||
material from exfiltration. Specifically, the workload asks the Secure Session
|
||||
Agent for the TLS configuration to use during the handshake, to perform private
|
||||
key operations, and to validate the peer certificate chain. The Secure Session
|
||||
Agent's client libraries enable applications to communicate with the Secure
|
||||
Session Agent during the TLS handshake, and to encrypt traffic to the peer
|
||||
after the TLS handshake is complete.
|
||||
|
||||
This repository contains the source code for the Secure Session Agent's Go
|
||||
client libraries, which allow gRPC-Go applications to use the Secure Session
|
||||
Agent. This repository supports the Bazel and Golang build systems.
|
||||
|
||||
All code in this repository is experimental and subject to change. We do not
|
||||
guarantee API stability at this time.
|
||||
167
vendor/github.com/google/s2a-go/fallback/s2a_fallback.go
generated
vendored
Normal file
167
vendor/github.com/google/s2a-go/fallback/s2a_fallback.go
generated
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2023 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
|
||||
*
|
||||
* https://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 fallback provides default implementations of fallback options when S2A fails.
|
||||
package fallback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
const (
|
||||
alpnProtoStrH2 = "h2"
|
||||
alpnProtoStrHTTP = "http/1.1"
|
||||
defaultHTTPSPort = "443"
|
||||
)
|
||||
|
||||
// FallbackTLSConfigGRPC is a tls.Config used by the DefaultFallbackClientHandshakeFunc function.
|
||||
// It supports GRPC use case, thus the alpn is set to 'h2'.
|
||||
var FallbackTLSConfigGRPC = tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
ClientSessionCache: nil,
|
||||
NextProtos: []string{alpnProtoStrH2},
|
||||
}
|
||||
|
||||
// FallbackTLSConfigHTTP is a tls.Config used by the DefaultFallbackDialerAndAddress func.
|
||||
// It supports the HTTP use case and the alpn is set to both 'http/1.1' and 'h2'.
|
||||
var FallbackTLSConfigHTTP = tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
ClientSessionCache: nil,
|
||||
NextProtos: []string{alpnProtoStrH2, alpnProtoStrHTTP},
|
||||
}
|
||||
|
||||
// ClientHandshake establishes a TLS connection and returns it, plus its auth info.
|
||||
// Inputs:
|
||||
//
|
||||
// targetServer: the server attempted with S2A.
|
||||
// conn: the tcp connection to the server at address targetServer that was passed into S2A's ClientHandshake func.
|
||||
// If fallback is successful, the `conn` should be closed.
|
||||
// err: the error encountered when performing the client-side TLS handshake with S2A.
|
||||
type ClientHandshake func(ctx context.Context, targetServer string, conn net.Conn, err error) (net.Conn, credentials.AuthInfo, error)
|
||||
|
||||
// DefaultFallbackClientHandshakeFunc returns a ClientHandshake function,
|
||||
// which establishes a TLS connection to the provided fallbackAddr, returns the new connection and its auth info.
|
||||
// Example use:
|
||||
//
|
||||
// transportCreds, _ = s2a.NewClientCreds(&s2a.ClientOptions{
|
||||
// S2AAddress: s2aAddress,
|
||||
// FallbackOpts: &s2a.FallbackOptions{ // optional
|
||||
// FallbackClientHandshakeFunc: fallback.DefaultFallbackClientHandshakeFunc(fallbackAddr),
|
||||
// },
|
||||
// })
|
||||
//
|
||||
// The fallback server's certificate must be verifiable using OS root store.
|
||||
// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
|
||||
// it uses default port 443.
|
||||
// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
|
||||
// and min TLS version is set to 1.3.
|
||||
func DefaultFallbackClientHandshakeFunc(fallbackAddr string) (ClientHandshake, error) {
|
||||
var fallbackDialer = tls.Dialer{Config: &FallbackTLSConfigGRPC}
|
||||
return defaultFallbackClientHandshakeFuncInternal(fallbackAddr, fallbackDialer.DialContext)
|
||||
}
|
||||
|
||||
func defaultFallbackClientHandshakeFuncInternal(fallbackAddr string, dialContextFunc func(context.Context, string, string) (net.Conn, error)) (ClientHandshake, error) {
|
||||
fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
|
||||
if err != nil {
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return func(ctx context.Context, targetServer string, conn net.Conn, s2aErr error) (net.Conn, credentials.AuthInfo, error) {
|
||||
fbConn, fbErr := dialContextFunc(ctx, "tcp", fallbackServerAddr)
|
||||
if fbErr != nil {
|
||||
grpclog.Infof("dialing to fallback server %s failed: %v", fallbackServerAddr, fbErr)
|
||||
return nil, nil, fmt.Errorf("dialing to fallback server %s failed: %v; S2A client handshake with %s error: %w", fallbackServerAddr, fbErr, targetServer, s2aErr)
|
||||
}
|
||||
|
||||
tc, success := fbConn.(*tls.Conn)
|
||||
if !success {
|
||||
grpclog.Infof("the connection with fallback server is expected to be tls but isn't")
|
||||
return nil, nil, fmt.Errorf("the connection with fallback server is expected to be tls but isn't; S2A client handshake with %s error: %w", targetServer, s2aErr)
|
||||
}
|
||||
|
||||
tlsInfo := credentials.TLSInfo{
|
||||
State: tc.ConnectionState(),
|
||||
CommonAuthInfo: credentials.CommonAuthInfo{
|
||||
SecurityLevel: credentials.PrivacyAndIntegrity,
|
||||
},
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("ConnectionState.NegotiatedProtocol: %v", tc.ConnectionState().NegotiatedProtocol)
|
||||
grpclog.Infof("ConnectionState.HandshakeComplete: %v", tc.ConnectionState().HandshakeComplete)
|
||||
grpclog.Infof("ConnectionState.ServerName: %v", tc.ConnectionState().ServerName)
|
||||
}
|
||||
conn.Close()
|
||||
return fbConn, tlsInfo, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DefaultFallbackDialerAndAddress returns a TLS dialer and the network address to dial.
|
||||
// Example use:
|
||||
//
|
||||
// fallbackDialer, fallbackServerAddr := fallback.DefaultFallbackDialerAndAddress(fallbackAddr)
|
||||
// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
|
||||
// S2AAddress: s2aAddress, // required
|
||||
// FallbackOpts: &s2a.FallbackOptions{
|
||||
// FallbackDialer: &s2a.FallbackDialer{
|
||||
// Dialer: fallbackDialer,
|
||||
// ServerAddr: fallbackServerAddr,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
//
|
||||
// The fallback server's certificate should be verifiable using OS root store.
|
||||
// The fallbackAddr is expected to be a network address, e.g. example.com:port. If port is not specified,
|
||||
// it uses default port 443.
|
||||
// In the returned function's TLS config, ClientSessionCache is explicitly set to nil to disable TLS resumption,
|
||||
// and min TLS version is set to 1.3.
|
||||
func DefaultFallbackDialerAndAddress(fallbackAddr string) (*tls.Dialer, string, error) {
|
||||
fallbackServerAddr, err := processFallbackAddr(fallbackAddr)
|
||||
if err != nil {
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("error processing fallback address [%s]: %v", fallbackAddr, err)
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
return &tls.Dialer{Config: &FallbackTLSConfigHTTP}, fallbackServerAddr, nil
|
||||
}
|
||||
|
||||
func processFallbackAddr(fallbackAddr string) (string, error) {
|
||||
var fallbackServerAddr string
|
||||
var err error
|
||||
|
||||
if fallbackAddr == "" {
|
||||
return "", fmt.Errorf("empty fallback address")
|
||||
}
|
||||
_, _, err = net.SplitHostPort(fallbackAddr)
|
||||
if err != nil {
|
||||
// fallbackAddr does not have port suffix
|
||||
fallbackServerAddr = net.JoinHostPort(fallbackAddr, defaultHTTPSPort)
|
||||
} else {
|
||||
// FallbackServerAddr already has port suffix
|
||||
fallbackServerAddr = fallbackAddr
|
||||
}
|
||||
return fallbackServerAddr, nil
|
||||
}
|
||||
119
vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go
generated
vendored
Normal file
119
vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go
generated
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 authinfo provides authentication and authorization information that
|
||||
// results from the TLS handshake.
|
||||
package authinfo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
contextpb "github.com/google/s2a-go/internal/proto/s2a_context_go_proto"
|
||||
grpcpb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
var _ credentials.AuthInfo = (*S2AAuthInfo)(nil)
|
||||
|
||||
const s2aAuthType = "s2a"
|
||||
|
||||
// S2AAuthInfo exposes authentication and authorization information from the
|
||||
// S2A session result to the gRPC stack.
|
||||
type S2AAuthInfo struct {
|
||||
s2aContext *contextpb.S2AContext
|
||||
commonAuthInfo credentials.CommonAuthInfo
|
||||
}
|
||||
|
||||
// NewS2AAuthInfo returns a new S2AAuthInfo object from the S2A session result.
|
||||
func NewS2AAuthInfo(result *grpcpb.SessionResult) (credentials.AuthInfo, error) {
|
||||
return newS2AAuthInfo(result)
|
||||
}
|
||||
|
||||
func newS2AAuthInfo(result *grpcpb.SessionResult) (*S2AAuthInfo, error) {
|
||||
if result == nil {
|
||||
return nil, errors.New("NewS2aAuthInfo given nil session result")
|
||||
}
|
||||
return &S2AAuthInfo{
|
||||
s2aContext: &contextpb.S2AContext{
|
||||
ApplicationProtocol: result.GetApplicationProtocol(),
|
||||
TlsVersion: result.GetState().GetTlsVersion(),
|
||||
Ciphersuite: result.GetState().GetTlsCiphersuite(),
|
||||
PeerIdentity: result.GetPeerIdentity(),
|
||||
LocalIdentity: result.GetLocalIdentity(),
|
||||
PeerCertFingerprint: result.GetPeerCertFingerprint(),
|
||||
LocalCertFingerprint: result.GetLocalCertFingerprint(),
|
||||
IsHandshakeResumed: result.GetState().GetIsHandshakeResumed(),
|
||||
},
|
||||
commonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AuthType returns the authentication type.
|
||||
func (s *S2AAuthInfo) AuthType() string {
|
||||
return s2aAuthType
|
||||
}
|
||||
|
||||
// ApplicationProtocol returns the application protocol, e.g. "grpc".
|
||||
func (s *S2AAuthInfo) ApplicationProtocol() string {
|
||||
return s.s2aContext.GetApplicationProtocol()
|
||||
}
|
||||
|
||||
// TLSVersion returns the TLS version negotiated during the handshake.
|
||||
func (s *S2AAuthInfo) TLSVersion() commonpb.TLSVersion {
|
||||
return s.s2aContext.GetTlsVersion()
|
||||
}
|
||||
|
||||
// Ciphersuite returns the ciphersuite negotiated during the handshake.
|
||||
func (s *S2AAuthInfo) Ciphersuite() commonpb.Ciphersuite {
|
||||
return s.s2aContext.GetCiphersuite()
|
||||
}
|
||||
|
||||
// PeerIdentity returns the authenticated identity of the peer.
|
||||
func (s *S2AAuthInfo) PeerIdentity() *commonpb.Identity {
|
||||
return s.s2aContext.GetPeerIdentity()
|
||||
}
|
||||
|
||||
// LocalIdentity returns the local identity of the application used during
|
||||
// session setup.
|
||||
func (s *S2AAuthInfo) LocalIdentity() *commonpb.Identity {
|
||||
return s.s2aContext.GetLocalIdentity()
|
||||
}
|
||||
|
||||
// PeerCertFingerprint returns the SHA256 hash of the peer certificate used in
|
||||
// the S2A handshake.
|
||||
func (s *S2AAuthInfo) PeerCertFingerprint() []byte {
|
||||
return s.s2aContext.GetPeerCertFingerprint()
|
||||
}
|
||||
|
||||
// LocalCertFingerprint returns the SHA256 hash of the local certificate used
|
||||
// in the S2A handshake.
|
||||
func (s *S2AAuthInfo) LocalCertFingerprint() []byte {
|
||||
return s.s2aContext.GetLocalCertFingerprint()
|
||||
}
|
||||
|
||||
// IsHandshakeResumed returns true if a cached session was used to resume
|
||||
// the handshake.
|
||||
func (s *S2AAuthInfo) IsHandshakeResumed() bool {
|
||||
return s.s2aContext.GetIsHandshakeResumed()
|
||||
}
|
||||
|
||||
// SecurityLevel returns the security level of the connection.
|
||||
func (s *S2AAuthInfo) SecurityLevel() credentials.SecurityLevel {
|
||||
return s.commonAuthInfo.SecurityLevel
|
||||
}
|
||||
438
vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go
generated
vendored
Normal file
438
vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go
generated
vendored
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 handshaker communicates with the S2A handshaker service.
|
||||
package handshaker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/google/s2a-go/internal/authinfo"
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
|
||||
"github.com/google/s2a-go/internal/record"
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
grpc "google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
var (
|
||||
// appProtocol contains the application protocol accepted by the handshaker.
|
||||
appProtocol = "grpc"
|
||||
// frameLimit is the maximum size of a frame in bytes.
|
||||
frameLimit = 1024 * 64
|
||||
// peerNotRespondingError is the error thrown when the peer doesn't respond.
|
||||
errPeerNotResponding = errors.New("peer is not responding and re-connection should be attempted")
|
||||
)
|
||||
|
||||
// Handshaker defines a handshaker interface.
|
||||
type Handshaker interface {
|
||||
// ClientHandshake starts and completes a TLS handshake from the client side,
|
||||
// and returns a secure connection along with additional auth information.
|
||||
ClientHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
|
||||
// ServerHandshake starts and completes a TLS handshake from the server side,
|
||||
// and returns a secure connection along with additional auth information.
|
||||
ServerHandshake(ctx context.Context) (net.Conn, credentials.AuthInfo, error)
|
||||
// Close terminates the Handshaker. It should be called when the handshake
|
||||
// is complete.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// ClientHandshakerOptions contains the options needed to configure the S2A
|
||||
// handshaker service on the client-side.
|
||||
type ClientHandshakerOptions struct {
|
||||
// MinTLSVersion specifies the min TLS version supported by the client.
|
||||
MinTLSVersion commonpb.TLSVersion
|
||||
// MaxTLSVersion specifies the max TLS version supported by the client.
|
||||
MaxTLSVersion commonpb.TLSVersion
|
||||
// TLSCiphersuites is the ordered list of ciphersuites supported by the
|
||||
// client.
|
||||
TLSCiphersuites []commonpb.Ciphersuite
|
||||
// TargetIdentities contains a list of allowed server identities. One of the
|
||||
// target identities should match the peer identity in the handshake
|
||||
// result; otherwise, the handshake fails.
|
||||
TargetIdentities []*commonpb.Identity
|
||||
// LocalIdentity is the local identity of the client application. If none is
|
||||
// provided, then the S2A will choose the default identity.
|
||||
LocalIdentity *commonpb.Identity
|
||||
// TargetName is the allowed server name, which may be used for server
|
||||
// authorization check by the S2A if it is provided.
|
||||
TargetName string
|
||||
// EnsureProcessSessionTickets allows users to wait and ensure that all
|
||||
// available session tickets are sent to S2A before a process completes.
|
||||
EnsureProcessSessionTickets *sync.WaitGroup
|
||||
}
|
||||
|
||||
// ServerHandshakerOptions contains the options needed to configure the S2A
|
||||
// handshaker service on the server-side.
|
||||
type ServerHandshakerOptions struct {
|
||||
// MinTLSVersion specifies the min TLS version supported by the server.
|
||||
MinTLSVersion commonpb.TLSVersion
|
||||
// MaxTLSVersion specifies the max TLS version supported by the server.
|
||||
MaxTLSVersion commonpb.TLSVersion
|
||||
// TLSCiphersuites is the ordered list of ciphersuites supported by the
|
||||
// server.
|
||||
TLSCiphersuites []commonpb.Ciphersuite
|
||||
// LocalIdentities is the list of local identities that may be assumed by
|
||||
// the server. If no local identity is specified, then the S2A chooses a
|
||||
// default local identity.
|
||||
LocalIdentities []*commonpb.Identity
|
||||
}
|
||||
|
||||
// s2aHandshaker performs a TLS handshake using the S2A handshaker service.
|
||||
type s2aHandshaker struct {
|
||||
// stream is used to communicate with the S2A handshaker service.
|
||||
stream s2apb.S2AService_SetUpSessionClient
|
||||
// conn is the connection to the peer.
|
||||
conn net.Conn
|
||||
// clientOpts should be non-nil iff the handshaker is client-side.
|
||||
clientOpts *ClientHandshakerOptions
|
||||
// serverOpts should be non-nil iff the handshaker is server-side.
|
||||
serverOpts *ServerHandshakerOptions
|
||||
// isClient determines if the handshaker is client or server side.
|
||||
isClient bool
|
||||
// hsAddr stores the address of the S2A handshaker service.
|
||||
hsAddr string
|
||||
// tokenManager manages access tokens for authenticating to S2A.
|
||||
tokenManager tokenmanager.AccessTokenManager
|
||||
// localIdentities is the set of local identities for whom the
|
||||
// tokenManager should fetch a token when preparing a request to be
|
||||
// sent to S2A.
|
||||
localIdentities []*commonpb.Identity
|
||||
}
|
||||
|
||||
// NewClientHandshaker creates an s2aHandshaker instance that performs a
|
||||
// client-side TLS handshake using the S2A handshaker service.
|
||||
func NewClientHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ClientHandshakerOptions) (Handshaker, error) {
|
||||
stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
if err != nil {
|
||||
grpclog.Infof("failed to create single token access token manager: %v", err)
|
||||
}
|
||||
return newClientHandshaker(stream, c, hsAddr, opts, tokenManager), nil
|
||||
}
|
||||
|
||||
func newClientHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ClientHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker {
|
||||
var localIdentities []*commonpb.Identity
|
||||
if opts != nil {
|
||||
localIdentities = []*commonpb.Identity{opts.LocalIdentity}
|
||||
}
|
||||
return &s2aHandshaker{
|
||||
stream: stream,
|
||||
conn: c,
|
||||
clientOpts: opts,
|
||||
isClient: true,
|
||||
hsAddr: hsAddr,
|
||||
tokenManager: tokenManager,
|
||||
localIdentities: localIdentities,
|
||||
}
|
||||
}
|
||||
|
||||
// NewServerHandshaker creates an s2aHandshaker instance that performs a
|
||||
// server-side TLS handshake using the S2A handshaker service.
|
||||
func NewServerHandshaker(ctx context.Context, conn *grpc.ClientConn, c net.Conn, hsAddr string, opts *ServerHandshakerOptions) (Handshaker, error) {
|
||||
stream, err := s2apb.NewS2AServiceClient(conn).SetUpSession(ctx, grpc.WaitForReady(true))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
if err != nil {
|
||||
grpclog.Infof("failed to create single token access token manager: %v", err)
|
||||
}
|
||||
return newServerHandshaker(stream, c, hsAddr, opts, tokenManager), nil
|
||||
}
|
||||
|
||||
func newServerHandshaker(stream s2apb.S2AService_SetUpSessionClient, c net.Conn, hsAddr string, opts *ServerHandshakerOptions, tokenManager tokenmanager.AccessTokenManager) *s2aHandshaker {
|
||||
var localIdentities []*commonpb.Identity
|
||||
if opts != nil {
|
||||
localIdentities = opts.LocalIdentities
|
||||
}
|
||||
return &s2aHandshaker{
|
||||
stream: stream,
|
||||
conn: c,
|
||||
serverOpts: opts,
|
||||
isClient: false,
|
||||
hsAddr: hsAddr,
|
||||
tokenManager: tokenManager,
|
||||
localIdentities: localIdentities,
|
||||
}
|
||||
}
|
||||
|
||||
// ClientHandshake performs a client-side TLS handshake using the S2A handshaker
|
||||
// service. When complete, returns a TLS connection.
|
||||
func (h *s2aHandshaker) ClientHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) {
|
||||
if !h.isClient {
|
||||
return nil, nil, errors.New("only handshakers created using NewClientHandshaker can perform a client-side handshake")
|
||||
}
|
||||
// Extract the hostname from the target name. The target name is assumed to be an authority.
|
||||
hostname, _, err := net.SplitHostPort(h.clientOpts.TargetName)
|
||||
if err != nil {
|
||||
// If the target name had no host port or could not be parsed, use it as is.
|
||||
hostname = h.clientOpts.TargetName
|
||||
}
|
||||
|
||||
// Prepare a client start message to send to the S2A handshaker service.
|
||||
req := &s2apb.SessionReq{
|
||||
ReqOneof: &s2apb.SessionReq_ClientStart{
|
||||
ClientStart: &s2apb.ClientSessionStartReq{
|
||||
ApplicationProtocols: []string{appProtocol},
|
||||
MinTlsVersion: h.clientOpts.MinTLSVersion,
|
||||
MaxTlsVersion: h.clientOpts.MaxTLSVersion,
|
||||
TlsCiphersuites: h.clientOpts.TLSCiphersuites,
|
||||
TargetIdentities: h.clientOpts.TargetIdentities,
|
||||
LocalIdentity: h.clientOpts.LocalIdentity,
|
||||
TargetName: hostname,
|
||||
},
|
||||
},
|
||||
AuthMechanisms: h.getAuthMechanisms(),
|
||||
}
|
||||
conn, result, err := h.setUpSession(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authInfo, err := authinfo.NewS2AAuthInfo(result)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return conn, authInfo, nil
|
||||
}
|
||||
|
||||
// ServerHandshake performs a server-side TLS handshake using the S2A handshaker
|
||||
// service. When complete, returns a TLS connection.
|
||||
func (h *s2aHandshaker) ServerHandshake(_ context.Context) (net.Conn, credentials.AuthInfo, error) {
|
||||
if h.isClient {
|
||||
return nil, nil, errors.New("only handshakers created using NewServerHandshaker can perform a server-side handshake")
|
||||
}
|
||||
p := make([]byte, frameLimit)
|
||||
n, err := h.conn.Read(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Prepare a server start message to send to the S2A handshaker service.
|
||||
req := &s2apb.SessionReq{
|
||||
ReqOneof: &s2apb.SessionReq_ServerStart{
|
||||
ServerStart: &s2apb.ServerSessionStartReq{
|
||||
ApplicationProtocols: []string{appProtocol},
|
||||
MinTlsVersion: h.serverOpts.MinTLSVersion,
|
||||
MaxTlsVersion: h.serverOpts.MaxTLSVersion,
|
||||
TlsCiphersuites: h.serverOpts.TLSCiphersuites,
|
||||
LocalIdentities: h.serverOpts.LocalIdentities,
|
||||
InBytes: p[:n],
|
||||
},
|
||||
},
|
||||
AuthMechanisms: h.getAuthMechanisms(),
|
||||
}
|
||||
conn, result, err := h.setUpSession(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authInfo, err := authinfo.NewS2AAuthInfo(result)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return conn, authInfo, nil
|
||||
}
|
||||
|
||||
// setUpSession proxies messages between the peer and the S2A handshaker
|
||||
// service.
|
||||
func (h *s2aHandshaker) setUpSession(req *s2apb.SessionReq) (net.Conn, *s2apb.SessionResult, error) {
|
||||
resp, err := h.accessHandshakerService(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Check if the returned status is an error.
|
||||
if resp.GetStatus() != nil {
|
||||
if got, want := resp.GetStatus().Code, uint32(codes.OK); got != want {
|
||||
return nil, nil, fmt.Errorf("%v", resp.GetStatus().Details)
|
||||
}
|
||||
}
|
||||
// Calculate the extra unread bytes from the Session. Attempting to consume
|
||||
// more than the bytes sent will throw an error.
|
||||
var extra []byte
|
||||
if req.GetServerStart() != nil {
|
||||
if resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) {
|
||||
return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds")
|
||||
}
|
||||
extra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():]
|
||||
}
|
||||
result, extra, err := h.processUntilDone(resp, extra)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if result.GetLocalIdentity() == nil {
|
||||
return nil, nil, errors.New("local identity must be populated in session result")
|
||||
}
|
||||
|
||||
// Create a new TLS record protocol using the Session Result.
|
||||
newConn, err := record.NewConn(&record.ConnParameters{
|
||||
NetConn: h.conn,
|
||||
Ciphersuite: result.GetState().GetTlsCiphersuite(),
|
||||
TLSVersion: result.GetState().GetTlsVersion(),
|
||||
InTrafficSecret: result.GetState().GetInKey(),
|
||||
OutTrafficSecret: result.GetState().GetOutKey(),
|
||||
UnusedBuf: extra,
|
||||
InSequence: result.GetState().GetInSequence(),
|
||||
OutSequence: result.GetState().GetOutSequence(),
|
||||
HSAddr: h.hsAddr,
|
||||
ConnectionID: result.GetState().GetConnectionId(),
|
||||
LocalIdentity: result.GetLocalIdentity(),
|
||||
EnsureProcessSessionTickets: h.ensureProcessSessionTickets(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return newConn, result, nil
|
||||
}
|
||||
|
||||
func (h *s2aHandshaker) ensureProcessSessionTickets() *sync.WaitGroup {
|
||||
if h.clientOpts == nil {
|
||||
return nil
|
||||
}
|
||||
return h.clientOpts.EnsureProcessSessionTickets
|
||||
}
|
||||
|
||||
// accessHandshakerService sends the session request to the S2A handshaker
|
||||
// service and returns the session response.
|
||||
func (h *s2aHandshaker) accessHandshakerService(req *s2apb.SessionReq) (*s2apb.SessionResp, error) {
|
||||
if err := h.stream.Send(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := h.stream.Recv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// processUntilDone continues proxying messages between the peer and the S2A
|
||||
// handshaker service until the handshaker service returns the SessionResult at
|
||||
// the end of the handshake or an error occurs.
|
||||
func (h *s2aHandshaker) processUntilDone(resp *s2apb.SessionResp, unusedBytes []byte) (*s2apb.SessionResult, []byte, error) {
|
||||
for {
|
||||
if len(resp.OutFrames) > 0 {
|
||||
if _, err := h.conn.Write(resp.OutFrames); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
if resp.Result != nil {
|
||||
return resp.Result, unusedBytes, nil
|
||||
}
|
||||
buf := make([]byte, frameLimit)
|
||||
n, err := h.conn.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, nil, err
|
||||
}
|
||||
// If there is nothing to send to the handshaker service and nothing is
|
||||
// received from the peer, then we are stuck. This covers the case when
|
||||
// the peer is not responding. Note that handshaker service connection
|
||||
// issues are caught in accessHandshakerService before we even get
|
||||
// here.
|
||||
if len(resp.OutFrames) == 0 && n == 0 {
|
||||
return nil, nil, errPeerNotResponding
|
||||
}
|
||||
// Append extra bytes from the previous interaction with the handshaker
|
||||
// service with the current buffer read from conn.
|
||||
p := append(unusedBytes, buf[:n]...)
|
||||
// From here on, p and unusedBytes point to the same slice.
|
||||
resp, err = h.accessHandshakerService(&s2apb.SessionReq{
|
||||
ReqOneof: &s2apb.SessionReq_Next{
|
||||
Next: &s2apb.SessionNextReq{
|
||||
InBytes: p,
|
||||
},
|
||||
},
|
||||
AuthMechanisms: h.getAuthMechanisms(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Cache the local identity returned by S2A, if it is populated. This
|
||||
// overwrites any existing local identities. This is done because, once the
|
||||
// S2A has selected a local identity, then only that local identity should
|
||||
// be asserted in future requests until the end of the current handshake.
|
||||
if resp.GetLocalIdentity() != nil {
|
||||
h.localIdentities = []*commonpb.Identity{resp.GetLocalIdentity()}
|
||||
}
|
||||
|
||||
// Set unusedBytes based on the handshaker service response.
|
||||
if resp.GetBytesConsumed() > uint32(len(p)) {
|
||||
return nil, nil, errors.New("handshaker service consumed bytes value is out-of-bounds")
|
||||
}
|
||||
unusedBytes = p[resp.GetBytesConsumed():]
|
||||
}
|
||||
}
|
||||
|
||||
// Close shuts down the handshaker and the stream to the S2A handshaker service
|
||||
// when the handshake is complete. It should be called when the caller obtains
|
||||
// the secure connection at the end of the handshake.
|
||||
func (h *s2aHandshaker) Close() error {
|
||||
return h.stream.CloseSend()
|
||||
}
|
||||
|
||||
func (h *s2aHandshaker) getAuthMechanisms() []*s2apb.AuthenticationMechanism {
|
||||
if h.tokenManager == nil {
|
||||
return nil
|
||||
}
|
||||
// First handle the special case when no local identities have been provided
|
||||
// by the application. In this case, an AuthenticationMechanism with no local
|
||||
// identity will be sent.
|
||||
if len(h.localIdentities) == 0 {
|
||||
token, err := h.tokenManager.DefaultToken()
|
||||
if err != nil {
|
||||
grpclog.Infof("unable to get token for empty local identity: %v", err)
|
||||
return nil
|
||||
}
|
||||
return []*s2apb.AuthenticationMechanism{
|
||||
{
|
||||
MechanismOneof: &s2apb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Next, handle the case where the application (or the S2A) has provided
|
||||
// one or more local identities.
|
||||
var authMechanisms []*s2apb.AuthenticationMechanism
|
||||
for _, localIdentity := range h.localIdentities {
|
||||
token, err := h.tokenManager.Token(localIdentity)
|
||||
if err != nil {
|
||||
grpclog.Infof("unable to get token for local identity %v: %v", localIdentity, err)
|
||||
continue
|
||||
}
|
||||
|
||||
authMechanism := &s2apb.AuthenticationMechanism{
|
||||
Identity: localIdentity,
|
||||
MechanismOneof: &s2apb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
}
|
||||
authMechanisms = append(authMechanisms, authMechanism)
|
||||
}
|
||||
return authMechanisms
|
||||
}
|
||||
92
vendor/github.com/google/s2a-go/internal/handshaker/service/service.go
generated
vendored
Normal file
92
vendor/github.com/google/s2a-go/internal/handshaker/service/service.go
generated
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 service is a utility for calling the S2A handshaker service.
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/appengine"
|
||||
"google.golang.org/appengine/socket"
|
||||
grpc "google.golang.org/grpc"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
var (
|
||||
// enableAppEngineDialer indicates whether an AppEngine-specific dial option
|
||||
// should be used.
|
||||
enableAppEngineDialer bool
|
||||
// appEngineDialerHook is an AppEngine-specific dial option that is set
|
||||
// during init time. If nil, then the application is not running on Google
|
||||
// AppEngine.
|
||||
appEngineDialerHook func(context.Context) grpc.DialOption
|
||||
// mu guards hsConnMap and hsDialer.
|
||||
mu sync.Mutex
|
||||
// hsConnMap represents a mapping from an S2A handshaker service address
|
||||
// to a corresponding connection to an S2A handshaker service instance.
|
||||
hsConnMap = make(map[string]*grpc.ClientConn)
|
||||
// hsDialer will be reassigned in tests.
|
||||
hsDialer = grpc.Dial
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&enableAppEngineDialer, "s2a_enable_appengine_dialer", false, "If true, opportunistically use AppEngine-specific dialer to call S2A.")
|
||||
if !appengine.IsAppEngine() && !appengine.IsDevAppServer() {
|
||||
return
|
||||
}
|
||||
appEngineDialerHook = func(ctx context.Context) grpc.DialOption {
|
||||
return grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return socket.DialTimeout(ctx, "tcp", addr, timeout)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Dial dials the S2A handshaker service. If a connection has already been
|
||||
// established, this function returns it. Otherwise, a new connection is
|
||||
// created.
|
||||
func Dial(handshakerServiceAddress string) (*grpc.ClientConn, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
hsConn, ok := hsConnMap[handshakerServiceAddress]
|
||||
if !ok {
|
||||
// Create a new connection to the S2A handshaker service. Note that
|
||||
// this connection stays open until the application is closed.
|
||||
grpcOpts := []grpc.DialOption{
|
||||
grpc.WithInsecure(),
|
||||
}
|
||||
if enableAppEngineDialer && appEngineDialerHook != nil {
|
||||
if grpclog.V(1) {
|
||||
grpclog.Info("Using AppEngine-specific dialer to talk to S2A.")
|
||||
}
|
||||
grpcOpts = append(grpcOpts, appEngineDialerHook(context.Background()))
|
||||
}
|
||||
var err error
|
||||
hsConn, err = hsDialer(handshakerServiceAddress, grpcOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hsConnMap[handshakerServiceAddress] = hsConn
|
||||
}
|
||||
return hsConn, nil
|
||||
}
|
||||
389
vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go
generated
vendored
Normal file
389
vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
// Copyright 2021 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: internal/proto/common/common.proto
|
||||
|
||||
package common_go_proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// The ciphersuites supported by S2A. The name determines the confidentiality,
|
||||
// and authentication ciphers as well as the hash algorithm used for PRF in
|
||||
// TLS 1.2 or HKDF in TLS 1.3. Thus, the components of the name are:
|
||||
// - AEAD -- for encryption and authentication, e.g., AES_128_GCM.
|
||||
// - Hash algorithm -- used in PRF or HKDF, e.g., SHA256.
|
||||
type Ciphersuite int32
|
||||
|
||||
const (
|
||||
Ciphersuite_AES_128_GCM_SHA256 Ciphersuite = 0
|
||||
Ciphersuite_AES_256_GCM_SHA384 Ciphersuite = 1
|
||||
Ciphersuite_CHACHA20_POLY1305_SHA256 Ciphersuite = 2
|
||||
)
|
||||
|
||||
// Enum value maps for Ciphersuite.
|
||||
var (
|
||||
Ciphersuite_name = map[int32]string{
|
||||
0: "AES_128_GCM_SHA256",
|
||||
1: "AES_256_GCM_SHA384",
|
||||
2: "CHACHA20_POLY1305_SHA256",
|
||||
}
|
||||
Ciphersuite_value = map[string]int32{
|
||||
"AES_128_GCM_SHA256": 0,
|
||||
"AES_256_GCM_SHA384": 1,
|
||||
"CHACHA20_POLY1305_SHA256": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Ciphersuite) Enum() *Ciphersuite {
|
||||
p := new(Ciphersuite)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Ciphersuite) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_common_common_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Ciphersuite) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_common_common_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Ciphersuite) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Ciphersuite.Descriptor instead.
|
||||
func (Ciphersuite) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// The TLS versions supported by S2A's handshaker module.
|
||||
type TLSVersion int32
|
||||
|
||||
const (
|
||||
TLSVersion_TLS1_2 TLSVersion = 0
|
||||
TLSVersion_TLS1_3 TLSVersion = 1
|
||||
)
|
||||
|
||||
// Enum value maps for TLSVersion.
|
||||
var (
|
||||
TLSVersion_name = map[int32]string{
|
||||
0: "TLS1_2",
|
||||
1: "TLS1_3",
|
||||
}
|
||||
TLSVersion_value = map[string]int32{
|
||||
"TLS1_2": 0,
|
||||
"TLS1_3": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x TLSVersion) Enum() *TLSVersion {
|
||||
p := new(TLSVersion)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x TLSVersion) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (TLSVersion) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_common_common_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (TLSVersion) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_common_common_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x TLSVersion) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TLSVersion.Descriptor instead.
|
||||
func (TLSVersion) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_common_common_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to IdentityOneof:
|
||||
//
|
||||
// *Identity_SpiffeId
|
||||
// *Identity_Hostname
|
||||
// *Identity_Uid
|
||||
// *Identity_MdbUsername
|
||||
// *Identity_GaiaId
|
||||
IdentityOneof isIdentity_IdentityOneof `protobuf_oneof:"identity_oneof"`
|
||||
// Additional identity-specific attributes.
|
||||
Attributes map[string]string `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *Identity) Reset() {
|
||||
*x = Identity{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_proto_common_common_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Identity) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Identity) ProtoMessage() {}
|
||||
|
||||
func (x *Identity) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_common_common_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Identity.ProtoReflect.Descriptor instead.
|
||||
func (*Identity) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_common_common_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (m *Identity) GetIdentityOneof() isIdentity_IdentityOneof {
|
||||
if m != nil {
|
||||
return m.IdentityOneof
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Identity) GetSpiffeId() string {
|
||||
if x, ok := x.GetIdentityOneof().(*Identity_SpiffeId); ok {
|
||||
return x.SpiffeId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identity) GetHostname() string {
|
||||
if x, ok := x.GetIdentityOneof().(*Identity_Hostname); ok {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identity) GetUid() string {
|
||||
if x, ok := x.GetIdentityOneof().(*Identity_Uid); ok {
|
||||
return x.Uid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identity) GetMdbUsername() string {
|
||||
if x, ok := x.GetIdentityOneof().(*Identity_MdbUsername); ok {
|
||||
return x.MdbUsername
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identity) GetGaiaId() string {
|
||||
if x, ok := x.GetIdentityOneof().(*Identity_GaiaId); ok {
|
||||
return x.GaiaId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identity) GetAttributes() map[string]string {
|
||||
if x != nil {
|
||||
return x.Attributes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isIdentity_IdentityOneof interface {
|
||||
isIdentity_IdentityOneof()
|
||||
}
|
||||
|
||||
type Identity_SpiffeId struct {
|
||||
// The SPIFFE ID of a connection endpoint.
|
||||
SpiffeId string `protobuf:"bytes,1,opt,name=spiffe_id,json=spiffeId,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Identity_Hostname struct {
|
||||
// The hostname of a connection endpoint.
|
||||
Hostname string `protobuf:"bytes,2,opt,name=hostname,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Identity_Uid struct {
|
||||
// The UID of a connection endpoint.
|
||||
Uid string `protobuf:"bytes,4,opt,name=uid,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Identity_MdbUsername struct {
|
||||
// The MDB username of a connection endpoint.
|
||||
MdbUsername string `protobuf:"bytes,5,opt,name=mdb_username,json=mdbUsername,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Identity_GaiaId struct {
|
||||
// The Gaia ID of a connection endpoint.
|
||||
GaiaId string `protobuf:"bytes,6,opt,name=gaia_id,json=gaiaId,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Identity_SpiffeId) isIdentity_IdentityOneof() {}
|
||||
|
||||
func (*Identity_Hostname) isIdentity_IdentityOneof() {}
|
||||
|
||||
func (*Identity_Uid) isIdentity_IdentityOneof() {}
|
||||
|
||||
func (*Identity_MdbUsername) isIdentity_IdentityOneof() {}
|
||||
|
||||
func (*Identity_GaiaId) isIdentity_IdentityOneof() {}
|
||||
|
||||
var File_internal_proto_common_common_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_internal_proto_common_common_proto_rawDesc = []byte{
|
||||
0x0a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
|
||||
0xb1, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1d, 0x0a, 0x09,
|
||||
0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
|
||||
0x00, 0x52, 0x08, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
|
||||
0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x75, 0x69, 0x64,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a,
|
||||
0x0c, 0x6d, 0x64, 0x62, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x64, 0x62, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x19, 0x0a, 0x07, 0x67, 0x61, 0x69, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x67, 0x61, 0x69, 0x61, 0x49, 0x64, 0x12, 0x43, 0x0a,
|
||||
0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x23, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
|
||||
0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x42, 0x10, 0x0a, 0x0e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x6e,
|
||||
0x65, 0x6f, 0x66, 0x2a, 0x5b, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69,
|
||||
0x74, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43,
|
||||
0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x45,
|
||||
0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34,
|
||||
0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50,
|
||||
0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x02,
|
||||
0x2a, 0x24, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a,
|
||||
0x0a, 0x06, 0x54, 0x4c, 0x53, 0x31, 0x5f, 0x32, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x4c,
|
||||
0x53, 0x31, 0x5f, 0x33, 0x10, 0x01, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_internal_proto_common_common_proto_rawDescOnce sync.Once
|
||||
file_internal_proto_common_common_proto_rawDescData = file_internal_proto_common_common_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_internal_proto_common_common_proto_rawDescGZIP() []byte {
|
||||
file_internal_proto_common_common_proto_rawDescOnce.Do(func() {
|
||||
file_internal_proto_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_common_common_proto_rawDescData)
|
||||
})
|
||||
return file_internal_proto_common_common_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_proto_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_internal_proto_common_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_internal_proto_common_common_proto_goTypes = []interface{}{
|
||||
(Ciphersuite)(0), // 0: s2a.proto.Ciphersuite
|
||||
(TLSVersion)(0), // 1: s2a.proto.TLSVersion
|
||||
(*Identity)(nil), // 2: s2a.proto.Identity
|
||||
nil, // 3: s2a.proto.Identity.AttributesEntry
|
||||
}
|
||||
var file_internal_proto_common_common_proto_depIdxs = []int32{
|
||||
3, // 0: s2a.proto.Identity.attributes:type_name -> s2a.proto.Identity.AttributesEntry
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_internal_proto_common_common_proto_init() }
|
||||
func file_internal_proto_common_common_proto_init() {
|
||||
if File_internal_proto_common_common_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_internal_proto_common_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Identity); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_internal_proto_common_common_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*Identity_SpiffeId)(nil),
|
||||
(*Identity_Hostname)(nil),
|
||||
(*Identity_Uid)(nil),
|
||||
(*Identity_MdbUsername)(nil),
|
||||
(*Identity_GaiaId)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_internal_proto_common_common_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_internal_proto_common_common_proto_goTypes,
|
||||
DependencyIndexes: file_internal_proto_common_common_proto_depIdxs,
|
||||
EnumInfos: file_internal_proto_common_common_proto_enumTypes,
|
||||
MessageInfos: file_internal_proto_common_common_proto_msgTypes,
|
||||
}.Build()
|
||||
File_internal_proto_common_common_proto = out.File
|
||||
file_internal_proto_common_common_proto_rawDesc = nil
|
||||
file_internal_proto_common_common_proto_goTypes = nil
|
||||
file_internal_proto_common_common_proto_depIdxs = nil
|
||||
}
|
||||
267
vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go
generated
vendored
Normal file
267
vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
// Copyright 2021 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: internal/proto/s2a_context/s2a_context.proto
|
||||
|
||||
package s2a_context_go_proto
|
||||
|
||||
import (
|
||||
common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type S2AContext struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The application protocol negotiated for this connection, e.g., 'grpc'.
|
||||
ApplicationProtocol string `protobuf:"bytes,1,opt,name=application_protocol,json=applicationProtocol,proto3" json:"application_protocol,omitempty"`
|
||||
// The TLS version number that the S2A's handshaker module used to set up the
|
||||
// session.
|
||||
TlsVersion common_go_proto.TLSVersion `protobuf:"varint,2,opt,name=tls_version,json=tlsVersion,proto3,enum=s2a.proto.TLSVersion" json:"tls_version,omitempty"`
|
||||
// The TLS ciphersuite negotiated by the S2A's handshaker module.
|
||||
Ciphersuite common_go_proto.Ciphersuite `protobuf:"varint,3,opt,name=ciphersuite,proto3,enum=s2a.proto.Ciphersuite" json:"ciphersuite,omitempty"`
|
||||
// The authenticated identity of the peer.
|
||||
PeerIdentity *common_go_proto.Identity `protobuf:"bytes,4,opt,name=peer_identity,json=peerIdentity,proto3" json:"peer_identity,omitempty"`
|
||||
// The local identity used during session setup. This could be:
|
||||
// - The local identity that the client specifies in ClientSessionStartReq.
|
||||
// - One of the local identities that the server specifies in
|
||||
// ServerSessionStartReq.
|
||||
// - If neither client or server specifies local identities, the S2A picks the
|
||||
// default one. In this case, this field will contain that identity.
|
||||
LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
|
||||
// The SHA256 hash of the peer certificate used in the handshake.
|
||||
PeerCertFingerprint []byte `protobuf:"bytes,6,opt,name=peer_cert_fingerprint,json=peerCertFingerprint,proto3" json:"peer_cert_fingerprint,omitempty"`
|
||||
// The SHA256 hash of the local certificate used in the handshake.
|
||||
LocalCertFingerprint []byte `protobuf:"bytes,7,opt,name=local_cert_fingerprint,json=localCertFingerprint,proto3" json:"local_cert_fingerprint,omitempty"`
|
||||
// Set to true if a cached session was reused to resume the handshake.
|
||||
IsHandshakeResumed bool `protobuf:"varint,8,opt,name=is_handshake_resumed,json=isHandshakeResumed,proto3" json:"is_handshake_resumed,omitempty"`
|
||||
}
|
||||
|
||||
func (x *S2AContext) Reset() {
|
||||
*x = S2AContext{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *S2AContext) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2AContext) ProtoMessage() {}
|
||||
|
||||
func (x *S2AContext) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead.
|
||||
func (*S2AContext) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetApplicationProtocol() string {
|
||||
if x != nil {
|
||||
return x.ApplicationProtocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetTlsVersion() common_go_proto.TLSVersion {
|
||||
if x != nil {
|
||||
return x.TlsVersion
|
||||
}
|
||||
return common_go_proto.TLSVersion(0)
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetCiphersuite() common_go_proto.Ciphersuite {
|
||||
if x != nil {
|
||||
return x.Ciphersuite
|
||||
}
|
||||
return common_go_proto.Ciphersuite(0)
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetPeerIdentity() *common_go_proto.Identity {
|
||||
if x != nil {
|
||||
return x.PeerIdentity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity {
|
||||
if x != nil {
|
||||
return x.LocalIdentity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetPeerCertFingerprint() []byte {
|
||||
if x != nil {
|
||||
return x.PeerCertFingerprint
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLocalCertFingerprint() []byte {
|
||||
if x != nil {
|
||||
return x.LocalCertFingerprint
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetIsHandshakeResumed() bool {
|
||||
if x != nil {
|
||||
return x.IsHandshakeResumed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_internal_proto_s2a_context_s2a_context_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_internal_proto_s2a_context_s2a_context_proto_rawDesc = []byte{
|
||||
0x0a, 0x2c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x73, 0x32, 0x61,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
|
||||
0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
|
||||
0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x03,
|
||||
0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x31, 0x0a, 0x14,
|
||||
0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c,
|
||||
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
|
||||
0x36, 0x0a, 0x0b, 0x74, 0x6c, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x74, 0x6c, 0x73,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65,
|
||||
0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x73,
|
||||
0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73,
|
||||
0x75, 0x69, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74,
|
||||
0x65, 0x12, 0x38, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70,
|
||||
0x65, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x0a, 0x0e, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49,
|
||||
0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x65, 0x72, 0x5f,
|
||||
0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74,
|
||||
0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72,
|
||||
0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x6c, 0x6f, 0x63,
|
||||
0x61, 0x6c, 0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e,
|
||||
0x74, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b,
|
||||
0x65, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x12, 0x69, 0x73, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6d, 0x65, 0x64, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x32, 0x61, 0x5f,
|
||||
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce sync.Once
|
||||
file_internal_proto_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_s2a_context_s2a_context_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_internal_proto_s2a_context_s2a_context_proto_rawDescGZIP() []byte {
|
||||
file_internal_proto_s2a_context_s2a_context_proto_rawDescOnce.Do(func() {
|
||||
file_internal_proto_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_s2a_context_s2a_context_proto_rawDescData)
|
||||
})
|
||||
return file_internal_proto_s2a_context_s2a_context_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_proto_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_internal_proto_s2a_context_s2a_context_proto_goTypes = []interface{}{
|
||||
(*S2AContext)(nil), // 0: s2a.proto.S2AContext
|
||||
(common_go_proto.TLSVersion)(0), // 1: s2a.proto.TLSVersion
|
||||
(common_go_proto.Ciphersuite)(0), // 2: s2a.proto.Ciphersuite
|
||||
(*common_go_proto.Identity)(nil), // 3: s2a.proto.Identity
|
||||
}
|
||||
var file_internal_proto_s2a_context_s2a_context_proto_depIdxs = []int32{
|
||||
1, // 0: s2a.proto.S2AContext.tls_version:type_name -> s2a.proto.TLSVersion
|
||||
2, // 1: s2a.proto.S2AContext.ciphersuite:type_name -> s2a.proto.Ciphersuite
|
||||
3, // 2: s2a.proto.S2AContext.peer_identity:type_name -> s2a.proto.Identity
|
||||
3, // 3: s2a.proto.S2AContext.local_identity:type_name -> s2a.proto.Identity
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_internal_proto_s2a_context_s2a_context_proto_init() }
|
||||
func file_internal_proto_s2a_context_s2a_context_proto_init() {
|
||||
if File_internal_proto_s2a_context_s2a_context_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_internal_proto_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*S2AContext); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_internal_proto_s2a_context_s2a_context_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_internal_proto_s2a_context_s2a_context_proto_goTypes,
|
||||
DependencyIndexes: file_internal_proto_s2a_context_s2a_context_proto_depIdxs,
|
||||
MessageInfos: file_internal_proto_s2a_context_s2a_context_proto_msgTypes,
|
||||
}.Build()
|
||||
File_internal_proto_s2a_context_s2a_context_proto = out.File
|
||||
file_internal_proto_s2a_context_s2a_context_proto_rawDesc = nil
|
||||
file_internal_proto_s2a_context_s2a_context_proto_goTypes = nil
|
||||
file_internal_proto_s2a_context_s2a_context_proto_depIdxs = nil
|
||||
}
|
||||
1377
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go
generated
vendored
Normal file
1377
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
173
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go
generated
vendored
Normal file
173
vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// Copyright 2021 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v3.21.12
|
||||
// source: internal/proto/s2a/s2a.proto
|
||||
|
||||
package s2a_go_proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
S2AService_SetUpSession_FullMethodName = "/s2a.proto.S2AService/SetUpSession"
|
||||
)
|
||||
|
||||
// S2AServiceClient is the client API for S2AService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type S2AServiceClient interface {
|
||||
// S2A service accepts a stream of session setup requests and returns a stream
|
||||
// of session setup responses. The client of this service is expected to send
|
||||
// exactly one client_start or server_start message followed by at least one
|
||||
// next message. Applications running TLS clients can send requests with
|
||||
// resumption_ticket messages only after the session is successfully set up.
|
||||
//
|
||||
// Every time S2A client sends a request, this service sends a response.
|
||||
// However, clients do not have to wait for service response before sending
|
||||
// the next request.
|
||||
SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error)
|
||||
}
|
||||
|
||||
type s2AServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient {
|
||||
return &s2AServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &s2AServiceSetUpSessionClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type S2AService_SetUpSessionClient interface {
|
||||
Send(*SessionReq) error
|
||||
Recv() (*SessionResp, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type s2AServiceSetUpSessionClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) {
|
||||
m := new(SessionResp)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// S2AServiceServer is the server API for S2AService service.
|
||||
// All implementations must embed UnimplementedS2AServiceServer
|
||||
// for forward compatibility
|
||||
type S2AServiceServer interface {
|
||||
// S2A service accepts a stream of session setup requests and returns a stream
|
||||
// of session setup responses. The client of this service is expected to send
|
||||
// exactly one client_start or server_start message followed by at least one
|
||||
// next message. Applications running TLS clients can send requests with
|
||||
// resumption_ticket messages only after the session is successfully set up.
|
||||
//
|
||||
// Every time S2A client sends a request, this service sends a response.
|
||||
// However, clients do not have to wait for service response before sending
|
||||
// the next request.
|
||||
SetUpSession(S2AService_SetUpSessionServer) error
|
||||
mustEmbedUnimplementedS2AServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedS2AServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented")
|
||||
}
|
||||
func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {}
|
||||
|
||||
// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to S2AServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeS2AServiceServer interface {
|
||||
mustEmbedUnimplementedS2AServiceServer()
|
||||
}
|
||||
|
||||
func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) {
|
||||
s.RegisterService(&S2AService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream})
|
||||
}
|
||||
|
||||
type S2AService_SetUpSessionServer interface {
|
||||
Send(*SessionResp) error
|
||||
Recv() (*SessionReq, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type s2AServiceSetUpSessionServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) {
|
||||
m := new(SessionReq)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var S2AService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "s2a.proto.S2AService",
|
||||
HandlerType: (*S2AServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "SetUpSession",
|
||||
Handler: _S2AService_SetUpSession_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "internal/proto/s2a/s2a.proto",
|
||||
}
|
||||
367
vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go
generated
vendored
Normal file
367
vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
// 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: internal/proto/v2/common/common.proto
|
||||
|
||||
package common_go_proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// The TLS 1.0-1.2 ciphersuites that the application can negotiate when using
|
||||
// S2A.
|
||||
type Ciphersuite int32
|
||||
|
||||
const (
|
||||
Ciphersuite_CIPHERSUITE_UNSPECIFIED Ciphersuite = 0
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 Ciphersuite = 1
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Ciphersuite = 2
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 Ciphersuite = 3
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Ciphersuite = 4
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384 Ciphersuite = 5
|
||||
Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Ciphersuite = 6
|
||||
)
|
||||
|
||||
// Enum value maps for Ciphersuite.
|
||||
var (
|
||||
Ciphersuite_name = map[int32]string{
|
||||
0: "CIPHERSUITE_UNSPECIFIED",
|
||||
1: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
2: "CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
||||
3: "CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
4: "CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
5: "CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
6: "CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
}
|
||||
Ciphersuite_value = map[string]int32{
|
||||
"CIPHERSUITE_UNSPECIFIED": 0,
|
||||
"CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": 1,
|
||||
"CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": 2,
|
||||
"CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": 3,
|
||||
"CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256": 4,
|
||||
"CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384": 5,
|
||||
"CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": 6,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Ciphersuite) Enum() *Ciphersuite {
|
||||
p := new(Ciphersuite)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Ciphersuite) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Ciphersuite) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_v2_common_common_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Ciphersuite) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_v2_common_common_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Ciphersuite) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Ciphersuite.Descriptor instead.
|
||||
func (Ciphersuite) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// The TLS versions supported by S2A's handshaker module.
|
||||
type TLSVersion int32
|
||||
|
||||
const (
|
||||
TLSVersion_TLS_VERSION_UNSPECIFIED TLSVersion = 0
|
||||
TLSVersion_TLS_VERSION_1_0 TLSVersion = 1
|
||||
TLSVersion_TLS_VERSION_1_1 TLSVersion = 2
|
||||
TLSVersion_TLS_VERSION_1_2 TLSVersion = 3
|
||||
TLSVersion_TLS_VERSION_1_3 TLSVersion = 4
|
||||
)
|
||||
|
||||
// Enum value maps for TLSVersion.
|
||||
var (
|
||||
TLSVersion_name = map[int32]string{
|
||||
0: "TLS_VERSION_UNSPECIFIED",
|
||||
1: "TLS_VERSION_1_0",
|
||||
2: "TLS_VERSION_1_1",
|
||||
3: "TLS_VERSION_1_2",
|
||||
4: "TLS_VERSION_1_3",
|
||||
}
|
||||
TLSVersion_value = map[string]int32{
|
||||
"TLS_VERSION_UNSPECIFIED": 0,
|
||||
"TLS_VERSION_1_0": 1,
|
||||
"TLS_VERSION_1_1": 2,
|
||||
"TLS_VERSION_1_2": 3,
|
||||
"TLS_VERSION_1_3": 4,
|
||||
}
|
||||
)
|
||||
|
||||
func (x TLSVersion) Enum() *TLSVersion {
|
||||
p := new(TLSVersion)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x TLSVersion) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (TLSVersion) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_v2_common_common_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (TLSVersion) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_v2_common_common_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x TLSVersion) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TLSVersion.Descriptor instead.
|
||||
func (TLSVersion) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
// The side in the TLS connection.
|
||||
type ConnectionSide int32
|
||||
|
||||
const (
|
||||
ConnectionSide_CONNECTION_SIDE_UNSPECIFIED ConnectionSide = 0
|
||||
ConnectionSide_CONNECTION_SIDE_CLIENT ConnectionSide = 1
|
||||
ConnectionSide_CONNECTION_SIDE_SERVER ConnectionSide = 2
|
||||
)
|
||||
|
||||
// Enum value maps for ConnectionSide.
|
||||
var (
|
||||
ConnectionSide_name = map[int32]string{
|
||||
0: "CONNECTION_SIDE_UNSPECIFIED",
|
||||
1: "CONNECTION_SIDE_CLIENT",
|
||||
2: "CONNECTION_SIDE_SERVER",
|
||||
}
|
||||
ConnectionSide_value = map[string]int32{
|
||||
"CONNECTION_SIDE_UNSPECIFIED": 0,
|
||||
"CONNECTION_SIDE_CLIENT": 1,
|
||||
"CONNECTION_SIDE_SERVER": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x ConnectionSide) Enum() *ConnectionSide {
|
||||
p := new(ConnectionSide)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x ConnectionSide) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (ConnectionSide) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_v2_common_common_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (ConnectionSide) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_v2_common_common_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x ConnectionSide) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ConnectionSide.Descriptor instead.
|
||||
func (ConnectionSide) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
// The ALPN protocols that the application can negotiate during a TLS handshake.
|
||||
type AlpnProtocol int32
|
||||
|
||||
const (
|
||||
AlpnProtocol_ALPN_PROTOCOL_UNSPECIFIED AlpnProtocol = 0
|
||||
AlpnProtocol_ALPN_PROTOCOL_GRPC AlpnProtocol = 1
|
||||
AlpnProtocol_ALPN_PROTOCOL_HTTP2 AlpnProtocol = 2
|
||||
AlpnProtocol_ALPN_PROTOCOL_HTTP1_1 AlpnProtocol = 3
|
||||
)
|
||||
|
||||
// Enum value maps for AlpnProtocol.
|
||||
var (
|
||||
AlpnProtocol_name = map[int32]string{
|
||||
0: "ALPN_PROTOCOL_UNSPECIFIED",
|
||||
1: "ALPN_PROTOCOL_GRPC",
|
||||
2: "ALPN_PROTOCOL_HTTP2",
|
||||
3: "ALPN_PROTOCOL_HTTP1_1",
|
||||
}
|
||||
AlpnProtocol_value = map[string]int32{
|
||||
"ALPN_PROTOCOL_UNSPECIFIED": 0,
|
||||
"ALPN_PROTOCOL_GRPC": 1,
|
||||
"ALPN_PROTOCOL_HTTP2": 2,
|
||||
"ALPN_PROTOCOL_HTTP1_1": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x AlpnProtocol) Enum() *AlpnProtocol {
|
||||
p := new(AlpnProtocol)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x AlpnProtocol) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (AlpnProtocol) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_internal_proto_v2_common_common_proto_enumTypes[3].Descriptor()
|
||||
}
|
||||
|
||||
func (AlpnProtocol) Type() protoreflect.EnumType {
|
||||
return &file_internal_proto_v2_common_common_proto_enumTypes[3]
|
||||
}
|
||||
|
||||
func (x AlpnProtocol) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AlpnProtocol.Descriptor instead.
|
||||
func (AlpnProtocol) EnumDescriptor() ([]byte, []int) {
|
||||
return file_internal_proto_v2_common_common_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
var File_internal_proto_v2_common_common_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_internal_proto_v2_common_common_proto_rawDesc = []byte{
|
||||
0x0a, 0x25, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x76, 0x32, 0x2a, 0xee, 0x02, 0x0a, 0x0b, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72,
|
||||
0x73, 0x75, 0x69, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53,
|
||||
0x55, 0x49, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
|
||||
0x10, 0x00, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54,
|
||||
0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49,
|
||||
0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53,
|
||||
0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x01, 0x12, 0x33, 0x0a, 0x2f, 0x43, 0x49, 0x50, 0x48, 0x45,
|
||||
0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44,
|
||||
0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f,
|
||||
0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x39, 0x0a, 0x35,
|
||||
0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48,
|
||||
0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41,
|
||||
0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53,
|
||||
0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x03, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49, 0x50, 0x48, 0x45,
|
||||
0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41,
|
||||
0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43,
|
||||
0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x04, 0x12, 0x31, 0x0a, 0x2d, 0x43, 0x49,
|
||||
0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f,
|
||||
0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36,
|
||||
0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x05, 0x12, 0x37, 0x0a,
|
||||
0x33, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44,
|
||||
0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x43, 0x48, 0x41, 0x43,
|
||||
0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x5f, 0x53, 0x48,
|
||||
0x41, 0x32, 0x35, 0x36, 0x10, 0x06, 0x2a, 0x7d, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53,
|
||||
0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
|
||||
0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e,
|
||||
0x5f, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45,
|
||||
0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54,
|
||||
0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x32, 0x10, 0x03,
|
||||
0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f,
|
||||
0x31, 0x5f, 0x33, 0x10, 0x04, 0x2a, 0x69, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4e, 0x4e, 0x45,
|
||||
0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
|
||||
0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e,
|
||||
0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x43, 0x4c, 0x49, 0x45,
|
||||
0x4e, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49,
|
||||
0x4f, 0x4e, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02,
|
||||
0x2a, 0x79, 0x0a, 0x0c, 0x41, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x12, 0x1d, 0x0a, 0x19, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
|
||||
0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
|
||||
0x16, 0x0a, 0x12, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
|
||||
0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x4c, 0x50, 0x4e, 0x5f,
|
||||
0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x02,
|
||||
0x12, 0x19, 0x0a, 0x15, 0x41, 0x4c, 0x50, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
|
||||
0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x31, 0x5f, 0x31, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x67, 0x6f,
|
||||
0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_internal_proto_v2_common_common_proto_rawDescOnce sync.Once
|
||||
file_internal_proto_v2_common_common_proto_rawDescData = file_internal_proto_v2_common_common_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_internal_proto_v2_common_common_proto_rawDescGZIP() []byte {
|
||||
file_internal_proto_v2_common_common_proto_rawDescOnce.Do(func() {
|
||||
file_internal_proto_v2_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_common_common_proto_rawDescData)
|
||||
})
|
||||
return file_internal_proto_v2_common_common_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_proto_v2_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||
var file_internal_proto_v2_common_common_proto_goTypes = []interface{}{
|
||||
(Ciphersuite)(0), // 0: s2a.proto.v2.Ciphersuite
|
||||
(TLSVersion)(0), // 1: s2a.proto.v2.TLSVersion
|
||||
(ConnectionSide)(0), // 2: s2a.proto.v2.ConnectionSide
|
||||
(AlpnProtocol)(0), // 3: s2a.proto.v2.AlpnProtocol
|
||||
}
|
||||
var file_internal_proto_v2_common_common_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_internal_proto_v2_common_common_proto_init() }
|
||||
func file_internal_proto_v2_common_common_proto_init() {
|
||||
if File_internal_proto_v2_common_common_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_internal_proto_v2_common_common_proto_rawDesc,
|
||||
NumEnums: 4,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_internal_proto_v2_common_common_proto_goTypes,
|
||||
DependencyIndexes: file_internal_proto_v2_common_common_proto_depIdxs,
|
||||
EnumInfos: file_internal_proto_v2_common_common_proto_enumTypes,
|
||||
}.Build()
|
||||
File_internal_proto_v2_common_common_proto = out.File
|
||||
file_internal_proto_v2_common_common_proto_rawDesc = nil
|
||||
file_internal_proto_v2_common_common_proto_goTypes = nil
|
||||
file_internal_proto_v2_common_common_proto_depIdxs = nil
|
||||
}
|
||||
248
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go
generated
vendored
Normal file
248
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
// 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: internal/proto/v2/s2a_context/s2a_context.proto
|
||||
|
||||
package s2a_context_go_proto
|
||||
|
||||
import (
|
||||
common_go_proto "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type S2AContext struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// The SPIFFE ID from the peer leaf certificate, if present.
|
||||
//
|
||||
// This field is only populated if the leaf certificate is a valid SPIFFE
|
||||
// SVID; in particular, there is a unique URI SAN and this URI SAN is a valid
|
||||
// SPIFFE ID.
|
||||
LeafCertSpiffeId string `protobuf:"bytes,1,opt,name=leaf_cert_spiffe_id,json=leafCertSpiffeId,proto3" json:"leaf_cert_spiffe_id,omitempty"`
|
||||
// The URIs that are present in the SubjectAltName extension of the peer leaf
|
||||
// certificate.
|
||||
//
|
||||
// Note that the extracted URIs are not validated and may not be properly
|
||||
// formatted.
|
||||
LeafCertUris []string `protobuf:"bytes,2,rep,name=leaf_cert_uris,json=leafCertUris,proto3" json:"leaf_cert_uris,omitempty"`
|
||||
// The DNSNames that are present in the SubjectAltName extension of the peer
|
||||
// leaf certificate.
|
||||
LeafCertDnsnames []string `protobuf:"bytes,3,rep,name=leaf_cert_dnsnames,json=leafCertDnsnames,proto3" json:"leaf_cert_dnsnames,omitempty"`
|
||||
// The (ordered) list of fingerprints in the certificate chain used to verify
|
||||
// the given leaf certificate. The order MUST be from leaf certificate
|
||||
// fingerprint to root certificate fingerprint.
|
||||
//
|
||||
// A fingerprint is the base-64 encoding of the SHA256 hash of the
|
||||
// DER-encoding of a certificate. The list MAY be populated even if the peer
|
||||
// certificate chain was NOT validated successfully.
|
||||
PeerCertificateChainFingerprints []string `protobuf:"bytes,4,rep,name=peer_certificate_chain_fingerprints,json=peerCertificateChainFingerprints,proto3" json:"peer_certificate_chain_fingerprints,omitempty"`
|
||||
// The local identity used during session setup.
|
||||
LocalIdentity *common_go_proto.Identity `protobuf:"bytes,5,opt,name=local_identity,json=localIdentity,proto3" json:"local_identity,omitempty"`
|
||||
// The SHA256 hash of the DER-encoding of the local leaf certificate used in
|
||||
// the handshake.
|
||||
LocalLeafCertFingerprint []byte `protobuf:"bytes,6,opt,name=local_leaf_cert_fingerprint,json=localLeafCertFingerprint,proto3" json:"local_leaf_cert_fingerprint,omitempty"`
|
||||
}
|
||||
|
||||
func (x *S2AContext) Reset() {
|
||||
*x = S2AContext{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *S2AContext) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2AContext) ProtoMessage() {}
|
||||
|
||||
func (x *S2AContext) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2AContext.ProtoReflect.Descriptor instead.
|
||||
func (*S2AContext) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLeafCertSpiffeId() string {
|
||||
if x != nil {
|
||||
return x.LeafCertSpiffeId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLeafCertUris() []string {
|
||||
if x != nil {
|
||||
return x.LeafCertUris
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLeafCertDnsnames() []string {
|
||||
if x != nil {
|
||||
return x.LeafCertDnsnames
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetPeerCertificateChainFingerprints() []string {
|
||||
if x != nil {
|
||||
return x.PeerCertificateChainFingerprints
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLocalIdentity() *common_go_proto.Identity {
|
||||
if x != nil {
|
||||
return x.LocalIdentity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *S2AContext) GetLocalLeafCertFingerprint() []byte {
|
||||
if x != nil {
|
||||
return x.LocalLeafCertFingerprint
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_internal_proto_v2_s2a_context_s2a_context_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = []byte{
|
||||
0x0a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2f,
|
||||
0x73, 0x32, 0x61, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x0c, 0x73, 0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x32, 0x1a,
|
||||
0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x02, 0x0a, 0x0a, 0x53, 0x32, 0x41, 0x43, 0x6f, 0x6e, 0x74, 0x65,
|
||||
0x78, 0x74, 0x12, 0x2d, 0x0a, 0x13, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f,
|
||||
0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49,
|
||||
0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x75,
|
||||
0x72, 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x66, 0x43,
|
||||
0x65, 0x72, 0x74, 0x55, 0x72, 0x69, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x65, 0x61, 0x66, 0x5f,
|
||||
0x63, 0x65, 0x72, 0x74, 0x5f, 0x64, 0x6e, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x44, 0x6e, 0x73,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x23, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65,
|
||||
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f,
|
||||
0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x20, 0x70, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
||||
0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72,
|
||||
0x69, 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73,
|
||||
0x32, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x12, 0x3d, 0x0a, 0x1b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63,
|
||||
0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x18, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4c, 0x65, 0x61, 0x66,
|
||||
0x43, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x42,
|
||||
0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x73, 0x32, 0x61, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x32, 0x61, 0x5f, 0x63,
|
||||
0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x67, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce sync.Once
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescGZIP() []byte {
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescOnce.Do(func() {
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData)
|
||||
})
|
||||
return file_internal_proto_v2_s2a_context_s2a_context_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = []interface{}{
|
||||
(*S2AContext)(nil), // 0: s2a.proto.v2.S2AContext
|
||||
(*common_go_proto.Identity)(nil), // 1: s2a.proto.Identity
|
||||
}
|
||||
var file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = []int32{
|
||||
1, // 0: s2a.proto.v2.S2AContext.local_identity:type_name -> s2a.proto.Identity
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_internal_proto_v2_s2a_context_s2a_context_proto_init() }
|
||||
func file_internal_proto_v2_s2a_context_s2a_context_proto_init() {
|
||||
if File_internal_proto_v2_s2a_context_s2a_context_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*S2AContext); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes,
|
||||
DependencyIndexes: file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs,
|
||||
MessageInfos: file_internal_proto_v2_s2a_context_s2a_context_proto_msgTypes,
|
||||
}.Build()
|
||||
File_internal_proto_v2_s2a_context_s2a_context_proto = out.File
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_rawDesc = nil
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_goTypes = nil
|
||||
file_internal_proto_v2_s2a_context_s2a_context_proto_depIdxs = nil
|
||||
}
|
||||
2480
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go
generated
vendored
Normal file
2480
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
159
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go
generated
vendored
Normal file
159
vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
// 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v3.21.12
|
||||
// source: internal/proto/v2/s2a/s2a.proto
|
||||
|
||||
package s2a_go_proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
S2AService_SetUpSession_FullMethodName = "/s2a.proto.v2.S2AService/SetUpSession"
|
||||
)
|
||||
|
||||
// S2AServiceClient is the client API for S2AService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type S2AServiceClient interface {
|
||||
// SetUpSession is a bidirectional stream used by applications to offload
|
||||
// operations from the TLS handshake.
|
||||
SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error)
|
||||
}
|
||||
|
||||
type s2AServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewS2AServiceClient(cc grpc.ClientConnInterface) S2AServiceClient {
|
||||
return &s2AServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *s2AServiceClient) SetUpSession(ctx context.Context, opts ...grpc.CallOption) (S2AService_SetUpSessionClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &S2AService_ServiceDesc.Streams[0], S2AService_SetUpSession_FullMethodName, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &s2AServiceSetUpSessionClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type S2AService_SetUpSessionClient interface {
|
||||
Send(*SessionReq) error
|
||||
Recv() (*SessionResp, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type s2AServiceSetUpSessionClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionClient) Send(m *SessionReq) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionClient) Recv() (*SessionResp, error) {
|
||||
m := new(SessionResp)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// S2AServiceServer is the server API for S2AService service.
|
||||
// All implementations must embed UnimplementedS2AServiceServer
|
||||
// for forward compatibility
|
||||
type S2AServiceServer interface {
|
||||
// SetUpSession is a bidirectional stream used by applications to offload
|
||||
// operations from the TLS handshake.
|
||||
SetUpSession(S2AService_SetUpSessionServer) error
|
||||
mustEmbedUnimplementedS2AServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedS2AServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedS2AServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedS2AServiceServer) SetUpSession(S2AService_SetUpSessionServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method SetUpSession not implemented")
|
||||
}
|
||||
func (UnimplementedS2AServiceServer) mustEmbedUnimplementedS2AServiceServer() {}
|
||||
|
||||
// UnsafeS2AServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to S2AServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeS2AServiceServer interface {
|
||||
mustEmbedUnimplementedS2AServiceServer()
|
||||
}
|
||||
|
||||
func RegisterS2AServiceServer(s grpc.ServiceRegistrar, srv S2AServiceServer) {
|
||||
s.RegisterService(&S2AService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _S2AService_SetUpSession_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(S2AServiceServer).SetUpSession(&s2AServiceSetUpSessionServer{stream})
|
||||
}
|
||||
|
||||
type S2AService_SetUpSessionServer interface {
|
||||
Send(*SessionResp) error
|
||||
Recv() (*SessionReq, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type s2AServiceSetUpSessionServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionServer) Send(m *SessionResp) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *s2AServiceSetUpSessionServer) Recv() (*SessionReq, error) {
|
||||
m := new(SessionReq)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// S2AService_ServiceDesc is the grpc.ServiceDesc for S2AService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var S2AService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "s2a.proto.v2.S2AService",
|
||||
HandlerType: (*S2AServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "SetUpSession",
|
||||
Handler: _S2AService_SetUpSession_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "internal/proto/v2/s2a/s2a.proto",
|
||||
}
|
||||
34
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go
generated
vendored
Normal file
34
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go
generated
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 aeadcrypter provides the interface for AEAD cipher implementations
|
||||
// used by S2A's record protocol.
|
||||
package aeadcrypter
|
||||
|
||||
// S2AAEADCrypter is the interface for an AEAD cipher used by the S2A record
|
||||
// protocol.
|
||||
type S2AAEADCrypter interface {
|
||||
// Encrypt encrypts the plaintext and computes the tag of dst and plaintext.
|
||||
// dst and plaintext may fully overlap or not at all.
|
||||
Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error)
|
||||
// Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may
|
||||
// fully overlap or not at all.
|
||||
Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error)
|
||||
// TagSize returns the tag size in bytes.
|
||||
TagSize() int
|
||||
}
|
||||
70
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go
generated
vendored
Normal file
70
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 aeadcrypter
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Supported key sizes in bytes.
|
||||
const (
|
||||
AES128GCMKeySize = 16
|
||||
AES256GCMKeySize = 32
|
||||
)
|
||||
|
||||
// aesgcm is the struct that holds an AES-GCM cipher for the S2A AEAD crypter.
|
||||
type aesgcm struct {
|
||||
aead cipher.AEAD
|
||||
}
|
||||
|
||||
// NewAESGCM creates an AES-GCM crypter instance. Note that the key must be
|
||||
// either 128 bits or 256 bits.
|
||||
func NewAESGCM(key []byte) (S2AAEADCrypter, error) {
|
||||
if len(key) != AES128GCMKeySize && len(key) != AES256GCMKeySize {
|
||||
return nil, fmt.Errorf("%d or %d bytes, given: %d", AES128GCMKeySize, AES256GCMKeySize, len(key))
|
||||
}
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a, err := cipher.NewGCM(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &aesgcm{aead: a}, nil
|
||||
}
|
||||
|
||||
// Encrypt is the encryption function. dst can contain bytes at the beginning of
|
||||
// the ciphertext that will not be encrypted but will be authenticated. If dst
|
||||
// has enough capacity to hold these bytes, the ciphertext and the tag, no
|
||||
// allocation and copy operations will be performed. dst and plaintext may
|
||||
// fully overlap or not at all.
|
||||
func (s *aesgcm) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) {
|
||||
return encrypt(s.aead, dst, plaintext, nonce, aad)
|
||||
}
|
||||
|
||||
func (s *aesgcm) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) {
|
||||
return decrypt(s.aead, dst, ciphertext, nonce, aad)
|
||||
}
|
||||
|
||||
func (s *aesgcm) TagSize() int {
|
||||
return TagSize
|
||||
}
|
||||
67
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go
generated
vendored
Normal file
67
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 aeadcrypter
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
)
|
||||
|
||||
// Supported key size in bytes.
|
||||
const (
|
||||
Chacha20Poly1305KeySize = 32
|
||||
)
|
||||
|
||||
// chachapoly is the struct that holds a CHACHA-POLY cipher for the S2A AEAD
|
||||
// crypter.
|
||||
type chachapoly struct {
|
||||
aead cipher.AEAD
|
||||
}
|
||||
|
||||
// NewChachaPoly creates a Chacha-Poly crypter instance. Note that the key must
|
||||
// be Chacha20Poly1305KeySize bytes in length.
|
||||
func NewChachaPoly(key []byte) (S2AAEADCrypter, error) {
|
||||
if len(key) != Chacha20Poly1305KeySize {
|
||||
return nil, fmt.Errorf("%d bytes, given: %d", Chacha20Poly1305KeySize, len(key))
|
||||
}
|
||||
c, err := chacha20poly1305.New(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &chachapoly{aead: c}, nil
|
||||
}
|
||||
|
||||
// Encrypt is the encryption function. dst can contain bytes at the beginning of
|
||||
// the ciphertext that will not be encrypted but will be authenticated. If dst
|
||||
// has enough capacity to hold these bytes, the ciphertext and the tag, no
|
||||
// allocation and copy operations will be performed. dst and plaintext may
|
||||
// fully overlap or not at all.
|
||||
func (s *chachapoly) Encrypt(dst, plaintext, nonce, aad []byte) ([]byte, error) {
|
||||
return encrypt(s.aead, dst, plaintext, nonce, aad)
|
||||
}
|
||||
|
||||
func (s *chachapoly) Decrypt(dst, ciphertext, nonce, aad []byte) ([]byte, error) {
|
||||
return decrypt(s.aead, dst, ciphertext, nonce, aad)
|
||||
}
|
||||
|
||||
func (s *chachapoly) TagSize() int {
|
||||
return TagSize
|
||||
}
|
||||
92
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go
generated
vendored
Normal file
92
vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go
generated
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 aeadcrypter
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
// TagSize is the tag size in bytes for AES-128-GCM-SHA256,
|
||||
// AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256.
|
||||
TagSize = 16
|
||||
// NonceSize is the size of the nonce in number of bytes for
|
||||
// AES-128-GCM-SHA256, AES-256-GCM-SHA384, and CHACHA20-POLY1305-SHA256.
|
||||
NonceSize = 12
|
||||
// SHA256DigestSize is the digest size of sha256 in bytes.
|
||||
SHA256DigestSize = 32
|
||||
// SHA384DigestSize is the digest size of sha384 in bytes.
|
||||
SHA384DigestSize = 48
|
||||
)
|
||||
|
||||
// sliceForAppend takes a slice and a requested number of bytes. It returns a
|
||||
// slice with the contents of the given slice followed by that many bytes and a
|
||||
// second slice that aliases into it and contains only the extra bytes. If the
|
||||
// original slice has sufficient capacity then no allocation is performed.
|
||||
func sliceForAppend(in []byte, n int) (head, tail []byte) {
|
||||
if total := len(in) + n; cap(in) >= total {
|
||||
head = in[:total]
|
||||
} else {
|
||||
head = make([]byte, total)
|
||||
copy(head, in)
|
||||
}
|
||||
tail = head[len(in):]
|
||||
return head, tail
|
||||
}
|
||||
|
||||
// encrypt is the encryption function for an AEAD crypter. aead determines
|
||||
// the type of AEAD crypter. dst can contain bytes at the beginning of the
|
||||
// ciphertext that will not be encrypted but will be authenticated. If dst has
|
||||
// enough capacity to hold these bytes, the ciphertext and the tag, no
|
||||
// allocation and copy operations will be performed. dst and plaintext may
|
||||
// fully overlap or not at all.
|
||||
func encrypt(aead cipher.AEAD, dst, plaintext, nonce, aad []byte) ([]byte, error) {
|
||||
if len(nonce) != NonceSize {
|
||||
return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce))
|
||||
}
|
||||
// If we need to allocate an output buffer, we want to include space for
|
||||
// the tag to avoid forcing the caller to reallocate as well.
|
||||
dlen := len(dst)
|
||||
dst, out := sliceForAppend(dst, len(plaintext)+TagSize)
|
||||
data := out[:len(plaintext)]
|
||||
copy(data, plaintext) // data may fully overlap plaintext
|
||||
|
||||
// Seal appends the ciphertext and the tag to its first argument and
|
||||
// returns the updated slice. However, sliceForAppend above ensures that
|
||||
// dst has enough capacity to avoid a reallocation and copy due to the
|
||||
// append.
|
||||
dst = aead.Seal(dst[:dlen], nonce, data, aad)
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// decrypt is the decryption function for an AEAD crypter, where aead determines
|
||||
// the type of AEAD crypter, and dst the destination bytes for the decrypted
|
||||
// ciphertext. The dst buffer may fully overlap with plaintext or not at all.
|
||||
func decrypt(aead cipher.AEAD, dst, ciphertext, nonce, aad []byte) ([]byte, error) {
|
||||
if len(nonce) != NonceSize {
|
||||
return nil, fmt.Errorf("nonce size must be %d bytes. received: %d", NonceSize, len(nonce))
|
||||
}
|
||||
// If dst is equal to ciphertext[:0], ciphertext storage is reused.
|
||||
plaintext, err := aead.Open(dst, nonce, ciphertext, aad)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("message auth failed: %v", err)
|
||||
}
|
||||
return plaintext, nil
|
||||
}
|
||||
98
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go
generated
vendored
Normal file
98
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go
generated
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 halfconn
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
"github.com/google/s2a-go/internal/record/internal/aeadcrypter"
|
||||
)
|
||||
|
||||
// ciphersuite is the interface for retrieving ciphersuite-specific information
|
||||
// and utilities.
|
||||
type ciphersuite interface {
|
||||
// keySize returns the key size in bytes. This refers to the key used by
|
||||
// the AEAD crypter. This is derived by calling HKDF expand on the traffic
|
||||
// secret.
|
||||
keySize() int
|
||||
// nonceSize returns the nonce size in bytes.
|
||||
nonceSize() int
|
||||
// trafficSecretSize returns the traffic secret size in bytes. This refers
|
||||
// to the secret used to derive the traffic key and nonce, as specified in
|
||||
// https://tools.ietf.org/html/rfc8446#section-7.
|
||||
trafficSecretSize() int
|
||||
// hashFunction returns the hash function for the ciphersuite.
|
||||
hashFunction() func() hash.Hash
|
||||
// aeadCrypter takes a key and creates an AEAD crypter for the ciphersuite
|
||||
// using that key.
|
||||
aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error)
|
||||
}
|
||||
|
||||
func newCiphersuite(ciphersuite s2apb.Ciphersuite) (ciphersuite, error) {
|
||||
switch ciphersuite {
|
||||
case s2apb.Ciphersuite_AES_128_GCM_SHA256:
|
||||
return &aesgcm128sha256{}, nil
|
||||
case s2apb.Ciphersuite_AES_256_GCM_SHA384:
|
||||
return &aesgcm256sha384{}, nil
|
||||
case s2apb.Ciphersuite_CHACHA20_POLY1305_SHA256:
|
||||
return &chachapolysha256{}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized ciphersuite: %v", ciphersuite)
|
||||
}
|
||||
}
|
||||
|
||||
// aesgcm128sha256 is the AES-128-GCM-SHA256 implementation of the ciphersuite
|
||||
// interface.
|
||||
type aesgcm128sha256 struct{}
|
||||
|
||||
func (aesgcm128sha256) keySize() int { return aeadcrypter.AES128GCMKeySize }
|
||||
func (aesgcm128sha256) nonceSize() int { return aeadcrypter.NonceSize }
|
||||
func (aesgcm128sha256) trafficSecretSize() int { return aeadcrypter.SHA256DigestSize }
|
||||
func (aesgcm128sha256) hashFunction() func() hash.Hash { return sha256.New }
|
||||
func (aesgcm128sha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
|
||||
return aeadcrypter.NewAESGCM(key)
|
||||
}
|
||||
|
||||
// aesgcm256sha384 is the AES-256-GCM-SHA384 implementation of the ciphersuite
|
||||
// interface.
|
||||
type aesgcm256sha384 struct{}
|
||||
|
||||
func (aesgcm256sha384) keySize() int { return aeadcrypter.AES256GCMKeySize }
|
||||
func (aesgcm256sha384) nonceSize() int { return aeadcrypter.NonceSize }
|
||||
func (aesgcm256sha384) trafficSecretSize() int { return aeadcrypter.SHA384DigestSize }
|
||||
func (aesgcm256sha384) hashFunction() func() hash.Hash { return sha512.New384 }
|
||||
func (aesgcm256sha384) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
|
||||
return aeadcrypter.NewAESGCM(key)
|
||||
}
|
||||
|
||||
// chachapolysha256 is the ChaChaPoly-SHA256 implementation of the ciphersuite
|
||||
// interface.
|
||||
type chachapolysha256 struct{}
|
||||
|
||||
func (chachapolysha256) keySize() int { return aeadcrypter.Chacha20Poly1305KeySize }
|
||||
func (chachapolysha256) nonceSize() int { return aeadcrypter.NonceSize }
|
||||
func (chachapolysha256) trafficSecretSize() int { return aeadcrypter.SHA256DigestSize }
|
||||
func (chachapolysha256) hashFunction() func() hash.Hash { return sha256.New }
|
||||
func (chachapolysha256) aeadCrypter(key []byte) (aeadcrypter.S2AAEADCrypter, error) {
|
||||
return aeadcrypter.NewChachaPoly(key)
|
||||
}
|
||||
60
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go
generated
vendored
Normal file
60
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 halfconn
|
||||
|
||||
import "errors"
|
||||
|
||||
// counter is a 64-bit counter.
|
||||
type counter struct {
|
||||
val uint64
|
||||
hasOverflowed bool
|
||||
}
|
||||
|
||||
// newCounter creates a new counter with the initial value set to val.
|
||||
func newCounter(val uint64) counter {
|
||||
return counter{val: val}
|
||||
}
|
||||
|
||||
// value returns the current value of the counter.
|
||||
func (c *counter) value() (uint64, error) {
|
||||
if c.hasOverflowed {
|
||||
return 0, errors.New("counter has overflowed")
|
||||
}
|
||||
return c.val, nil
|
||||
}
|
||||
|
||||
// increment increments the counter and checks for overflow.
|
||||
func (c *counter) increment() {
|
||||
// If the counter is already invalid due to overflow, there is no need to
|
||||
// increase it. We check for the hasOverflowed flag in the call to value().
|
||||
if c.hasOverflowed {
|
||||
return
|
||||
}
|
||||
c.val++
|
||||
if c.val == 0 {
|
||||
c.hasOverflowed = true
|
||||
}
|
||||
}
|
||||
|
||||
// reset sets the counter value to zero and sets the hasOverflowed flag to
|
||||
// false.
|
||||
func (c *counter) reset() {
|
||||
c.val = 0
|
||||
c.hasOverflowed = false
|
||||
}
|
||||
59
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go
generated
vendored
Normal file
59
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 halfconn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
"golang.org/x/crypto/hkdf"
|
||||
)
|
||||
|
||||
// hkdfExpander is the interface for the HKDF expansion function; see
|
||||
// https://tools.ietf.org/html/rfc5869 for details. its use in TLS 1.3 is
|
||||
// specified in https://tools.ietf.org/html/rfc8446#section-7.2
|
||||
type hkdfExpander interface {
|
||||
// expand takes a secret, a label, and the output length in bytes, and
|
||||
// returns the resulting expanded key.
|
||||
expand(secret, label []byte, length int) ([]byte, error)
|
||||
}
|
||||
|
||||
// defaultHKDFExpander is the default HKDF expander which uses Go's crypto/hkdf
|
||||
// for HKDF expansion.
|
||||
type defaultHKDFExpander struct {
|
||||
h func() hash.Hash
|
||||
}
|
||||
|
||||
// newDefaultHKDFExpander creates an instance of the default HKDF expander
|
||||
// using the given hash function.
|
||||
func newDefaultHKDFExpander(h func() hash.Hash) hkdfExpander {
|
||||
return &defaultHKDFExpander{h: h}
|
||||
}
|
||||
|
||||
func (d *defaultHKDFExpander) expand(secret, label []byte, length int) ([]byte, error) {
|
||||
outBuf := make([]byte, length)
|
||||
n, err := hkdf.Expand(d.h, secret, label).Read(outBuf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("hkdf.Expand.Read failed with error: %v", err)
|
||||
}
|
||||
if n < length {
|
||||
return nil, fmt.Errorf("hkdf.Expand.Read returned unexpected length, got %d, want %d", n, length)
|
||||
}
|
||||
return outBuf, nil
|
||||
}
|
||||
193
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go
generated
vendored
Normal file
193
vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go
generated
vendored
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 halfconn manages the inbound or outbound traffic of a TLS 1.3
|
||||
// connection.
|
||||
package halfconn
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
"github.com/google/s2a-go/internal/record/internal/aeadcrypter"
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
||||
// The constants below were taken from Section 7.2 and 7.3 in
|
||||
// https://tools.ietf.org/html/rfc8446#section-7. They are used as the label
|
||||
// in HKDF-Expand-Label.
|
||||
const (
|
||||
tls13Key = "tls13 key"
|
||||
tls13Nonce = "tls13 iv"
|
||||
tls13Update = "tls13 traffic upd"
|
||||
)
|
||||
|
||||
// S2AHalfConnection stores the state of the TLS 1.3 connection in the
|
||||
// inbound or outbound direction.
|
||||
type S2AHalfConnection struct {
|
||||
cs ciphersuite
|
||||
expander hkdfExpander
|
||||
// mutex guards sequence, aeadCrypter, trafficSecret, and nonce.
|
||||
mutex sync.Mutex
|
||||
aeadCrypter aeadcrypter.S2AAEADCrypter
|
||||
sequence counter
|
||||
trafficSecret []byte
|
||||
nonce []byte
|
||||
}
|
||||
|
||||
// New creates a new instance of S2AHalfConnection given a ciphersuite and a
|
||||
// traffic secret.
|
||||
func New(ciphersuite s2apb.Ciphersuite, trafficSecret []byte, sequence uint64) (*S2AHalfConnection, error) {
|
||||
cs, err := newCiphersuite(ciphersuite)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new ciphersuite: %v", ciphersuite)
|
||||
}
|
||||
if cs.trafficSecretSize() != len(trafficSecret) {
|
||||
return nil, fmt.Errorf("supplied traffic secret must be %v bytes, given: %v bytes", cs.trafficSecretSize(), len(trafficSecret))
|
||||
}
|
||||
|
||||
hc := &S2AHalfConnection{cs: cs, expander: newDefaultHKDFExpander(cs.hashFunction()), sequence: newCounter(sequence), trafficSecret: trafficSecret}
|
||||
if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil {
|
||||
return nil, fmt.Errorf("failed to create half connection using traffic secret: %v", err)
|
||||
}
|
||||
|
||||
return hc, nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts the plaintext and computes the tag of dst and plaintext.
|
||||
// dst and plaintext may fully overlap or not at all. Note that the sequence
|
||||
// number will still be incremented on failure, unless the sequence has
|
||||
// overflowed.
|
||||
func (hc *S2AHalfConnection) Encrypt(dst, plaintext, aad []byte) ([]byte, error) {
|
||||
hc.mutex.Lock()
|
||||
sequence, err := hc.getAndIncrementSequence()
|
||||
if err != nil {
|
||||
hc.mutex.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
nonce := hc.maskedNonce(sequence)
|
||||
crypter := hc.aeadCrypter
|
||||
hc.mutex.Unlock()
|
||||
return crypter.Encrypt(dst, plaintext, nonce, aad)
|
||||
}
|
||||
|
||||
// Decrypt decrypts ciphertext and verifies the tag. dst and ciphertext may
|
||||
// fully overlap or not at all. Note that the sequence number will still be
|
||||
// incremented on failure, unless the sequence has overflowed.
|
||||
func (hc *S2AHalfConnection) Decrypt(dst, ciphertext, aad []byte) ([]byte, error) {
|
||||
hc.mutex.Lock()
|
||||
sequence, err := hc.getAndIncrementSequence()
|
||||
if err != nil {
|
||||
hc.mutex.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
nonce := hc.maskedNonce(sequence)
|
||||
crypter := hc.aeadCrypter
|
||||
hc.mutex.Unlock()
|
||||
return crypter.Decrypt(dst, ciphertext, nonce, aad)
|
||||
}
|
||||
|
||||
// UpdateKey advances the traffic secret key, as specified in
|
||||
// https://tools.ietf.org/html/rfc8446#section-7.2. In addition, it derives
|
||||
// a new key and nonce, and resets the sequence number.
|
||||
func (hc *S2AHalfConnection) UpdateKey() error {
|
||||
hc.mutex.Lock()
|
||||
defer hc.mutex.Unlock()
|
||||
|
||||
var err error
|
||||
hc.trafficSecret, err = hc.deriveSecret(hc.trafficSecret, []byte(tls13Update), hc.cs.trafficSecretSize())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to derive traffic secret: %v", err)
|
||||
}
|
||||
|
||||
if err = hc.updateCrypterAndNonce(hc.trafficSecret); err != nil {
|
||||
return fmt.Errorf("failed to update half connection: %v", err)
|
||||
}
|
||||
|
||||
hc.sequence.reset()
|
||||
return nil
|
||||
}
|
||||
|
||||
// TagSize returns the tag size in bytes of the underlying AEAD crypter.
|
||||
func (hc *S2AHalfConnection) TagSize() int {
|
||||
return hc.aeadCrypter.TagSize()
|
||||
}
|
||||
|
||||
// updateCrypterAndNonce takes a new traffic secret and updates the crypter
|
||||
// and nonce. Note that the mutex must be held while calling this function.
|
||||
func (hc *S2AHalfConnection) updateCrypterAndNonce(newTrafficSecret []byte) error {
|
||||
key, err := hc.deriveSecret(newTrafficSecret, []byte(tls13Key), hc.cs.keySize())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update key: %v", err)
|
||||
}
|
||||
|
||||
hc.nonce, err = hc.deriveSecret(newTrafficSecret, []byte(tls13Nonce), hc.cs.nonceSize())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update nonce: %v", err)
|
||||
}
|
||||
|
||||
hc.aeadCrypter, err = hc.cs.aeadCrypter(key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update AEAD crypter: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAndIncrement returns the current sequence number and increments it. Note
|
||||
// that the mutex must be held while calling this function.
|
||||
func (hc *S2AHalfConnection) getAndIncrementSequence() (uint64, error) {
|
||||
sequence, err := hc.sequence.value()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hc.sequence.increment()
|
||||
return sequence, nil
|
||||
}
|
||||
|
||||
// maskedNonce creates a copy of the nonce that is masked with the sequence
|
||||
// number. Note that the mutex must be held while calling this function.
|
||||
func (hc *S2AHalfConnection) maskedNonce(sequence uint64) []byte {
|
||||
const uint64Size = 8
|
||||
nonce := make([]byte, len(hc.nonce))
|
||||
copy(nonce, hc.nonce)
|
||||
for i := 0; i < uint64Size; i++ {
|
||||
nonce[aeadcrypter.NonceSize-uint64Size+i] ^= byte(sequence >> uint64(56-uint64Size*i))
|
||||
}
|
||||
return nonce
|
||||
}
|
||||
|
||||
// deriveSecret implements the Derive-Secret function, as specified in
|
||||
// https://tools.ietf.org/html/rfc8446#section-7.1.
|
||||
func (hc *S2AHalfConnection) deriveSecret(secret, label []byte, length int) ([]byte, error) {
|
||||
var hkdfLabel cryptobyte.Builder
|
||||
hkdfLabel.AddUint16(uint16(length))
|
||||
hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||
b.AddBytes(label)
|
||||
})
|
||||
// Append an empty `Context` field to the label, as specified in the RFC.
|
||||
// The half connection does not use the `Context` field.
|
||||
hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||
b.AddBytes([]byte(""))
|
||||
})
|
||||
hkdfLabelBytes, err := hkdfLabel.Bytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("deriveSecret failed: %v", err)
|
||||
}
|
||||
return hc.expander.expand(secret, hkdfLabelBytes, length)
|
||||
}
|
||||
757
vendor/github.com/google/s2a-go/internal/record/record.go
generated
vendored
Normal file
757
vendor/github.com/google/s2a-go/internal/record/record.go
generated
vendored
Normal file
|
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 record implements the TLS 1.3 record protocol used by the S2A
|
||||
// transport credentials.
|
||||
package record
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
"github.com/google/s2a-go/internal/record/internal/halfconn"
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// recordType is the `ContentType` as described in
|
||||
// https://tools.ietf.org/html/rfc8446#section-5.1.
|
||||
type recordType byte
|
||||
|
||||
const (
|
||||
alert recordType = 21
|
||||
handshake recordType = 22
|
||||
applicationData recordType = 23
|
||||
)
|
||||
|
||||
// keyUpdateRequest is the `KeyUpdateRequest` as described in
|
||||
// https://tools.ietf.org/html/rfc8446#section-4.6.3.
|
||||
type keyUpdateRequest byte
|
||||
|
||||
const (
|
||||
updateNotRequested keyUpdateRequest = 0
|
||||
updateRequested keyUpdateRequest = 1
|
||||
)
|
||||
|
||||
// alertDescription is the `AlertDescription` as described in
|
||||
// https://tools.ietf.org/html/rfc8446#section-6.
|
||||
type alertDescription byte
|
||||
|
||||
const (
|
||||
closeNotify alertDescription = 0
|
||||
)
|
||||
|
||||
// sessionTicketState is used to determine whether session tickets have not yet
|
||||
// been received, are in the process of being received, or have finished
|
||||
// receiving.
|
||||
type sessionTicketState byte
|
||||
|
||||
const (
|
||||
ticketsNotYetReceived sessionTicketState = 0
|
||||
receivingTickets sessionTicketState = 1
|
||||
notReceivingTickets sessionTicketState = 2
|
||||
)
|
||||
|
||||
const (
|
||||
// The TLS 1.3-specific constants below (tlsRecordMaxPlaintextSize,
|
||||
// tlsRecordHeaderSize, tlsRecordTypeSize) were taken from
|
||||
// https://tools.ietf.org/html/rfc8446#section-5.1.
|
||||
|
||||
// tlsRecordMaxPlaintextSize is the maximum size in bytes of the plaintext
|
||||
// in a single TLS 1.3 record.
|
||||
tlsRecordMaxPlaintextSize = 16384 // 2^14
|
||||
// tlsRecordTypeSize is the size in bytes of the TLS 1.3 record type.
|
||||
tlsRecordTypeSize = 1
|
||||
// tlsTagSize is the size in bytes of the tag of the following three
|
||||
// ciphersuites: AES-128-GCM-SHA256, AES-256-GCM-SHA384,
|
||||
// CHACHA20-POLY1305-SHA256.
|
||||
tlsTagSize = 16
|
||||
// tlsRecordMaxPayloadSize is the maximum size in bytes of the payload in a
|
||||
// single TLS 1.3 record. This is the maximum size of the plaintext plus the
|
||||
// record type byte and 16 bytes of the tag.
|
||||
tlsRecordMaxPayloadSize = tlsRecordMaxPlaintextSize + tlsRecordTypeSize + tlsTagSize
|
||||
// tlsRecordHeaderTypeSize is the size in bytes of the TLS 1.3 record
|
||||
// header type.
|
||||
tlsRecordHeaderTypeSize = 1
|
||||
// tlsRecordHeaderLegacyRecordVersionSize is the size in bytes of the TLS
|
||||
// 1.3 record header legacy record version.
|
||||
tlsRecordHeaderLegacyRecordVersionSize = 2
|
||||
// tlsRecordHeaderPayloadLengthSize is the size in bytes of the TLS 1.3
|
||||
// record header payload length.
|
||||
tlsRecordHeaderPayloadLengthSize = 2
|
||||
// tlsRecordHeaderSize is the size in bytes of the TLS 1.3 record header.
|
||||
tlsRecordHeaderSize = tlsRecordHeaderTypeSize + tlsRecordHeaderLegacyRecordVersionSize + tlsRecordHeaderPayloadLengthSize
|
||||
// tlsRecordMaxSize
|
||||
tlsRecordMaxSize = tlsRecordMaxPayloadSize + tlsRecordHeaderSize
|
||||
// tlsApplicationData is the application data type of the TLS 1.3 record
|
||||
// header.
|
||||
tlsApplicationData = 23
|
||||
// tlsLegacyRecordVersion is the legacy record version of the TLS record.
|
||||
tlsLegacyRecordVersion = 3
|
||||
// tlsAlertSize is the size in bytes of an alert of TLS 1.3.
|
||||
tlsAlertSize = 2
|
||||
)
|
||||
|
||||
const (
|
||||
// These are TLS 1.3 handshake-specific constants.
|
||||
|
||||
// tlsHandshakeNewSessionTicketType is the prefix of a handshake new session
|
||||
// ticket message of TLS 1.3.
|
||||
tlsHandshakeNewSessionTicketType = 4
|
||||
// tlsHandshakeKeyUpdateType is the prefix of a handshake key update message
|
||||
// of TLS 1.3.
|
||||
tlsHandshakeKeyUpdateType = 24
|
||||
// tlsHandshakeMsgTypeSize is the size in bytes of the TLS 1.3 handshake
|
||||
// message type field.
|
||||
tlsHandshakeMsgTypeSize = 1
|
||||
// tlsHandshakeLengthSize is the size in bytes of the TLS 1.3 handshake
|
||||
// message length field.
|
||||
tlsHandshakeLengthSize = 3
|
||||
// tlsHandshakeKeyUpdateMsgSize is the size in bytes of the TLS 1.3
|
||||
// handshake key update message.
|
||||
tlsHandshakeKeyUpdateMsgSize = 1
|
||||
// tlsHandshakePrefixSize is the size in bytes of the prefix of the TLS 1.3
|
||||
// handshake message.
|
||||
tlsHandshakePrefixSize = 4
|
||||
// tlsMaxSessionTicketSize is the maximum size of a NewSessionTicket message
|
||||
// in TLS 1.3. This is the sum of the max sizes of all the fields in the
|
||||
// NewSessionTicket struct specified in
|
||||
// https://tools.ietf.org/html/rfc8446#section-4.6.1.
|
||||
tlsMaxSessionTicketSize = 131338
|
||||
)
|
||||
|
||||
const (
|
||||
// outBufMaxRecords is the maximum number of records that can fit in the
|
||||
// ourRecordsBuf buffer.
|
||||
outBufMaxRecords = 16
|
||||
// outBufMaxSize is the maximum size (in bytes) of the outRecordsBuf buffer.
|
||||
outBufMaxSize = outBufMaxRecords * tlsRecordMaxSize
|
||||
// maxAllowedTickets is the maximum number of session tickets that are
|
||||
// allowed. The number of tickets are limited to ensure that the size of the
|
||||
// ticket queue does not grow indefinitely. S2A also keeps a limit on the
|
||||
// number of tickets that it caches.
|
||||
maxAllowedTickets = 5
|
||||
)
|
||||
|
||||
// preConstructedKeyUpdateMsg holds the key update message. This is needed as an
|
||||
// optimization so that the same message does not need to be constructed every
|
||||
// time a key update message is sent.
|
||||
var preConstructedKeyUpdateMsg = buildKeyUpdateRequest()
|
||||
|
||||
// conn represents a secured TLS connection. It implements the net.Conn
|
||||
// interface.
|
||||
type conn struct {
|
||||
net.Conn
|
||||
// inConn is the half connection responsible for decrypting incoming bytes.
|
||||
inConn *halfconn.S2AHalfConnection
|
||||
// outConn is the half connection responsible for encrypting outgoing bytes.
|
||||
outConn *halfconn.S2AHalfConnection
|
||||
// pendingApplicationData holds data that has been read from the connection
|
||||
// and decrypted, but has not yet been returned by Read.
|
||||
pendingApplicationData []byte
|
||||
// unusedBuf holds data read from the network that has not yet been
|
||||
// decrypted. This data might not consist of a complete record. It may
|
||||
// consist of several records, the last of which could be incomplete.
|
||||
unusedBuf []byte
|
||||
// outRecordsBuf is a buffer used to store outgoing TLS records before
|
||||
// they are written to the network.
|
||||
outRecordsBuf []byte
|
||||
// nextRecord stores the next record info in the unusedBuf buffer.
|
||||
nextRecord []byte
|
||||
// overheadSize is the overhead size in bytes of each TLS 1.3 record, which
|
||||
// is computed as overheadSize = header size + record type byte + tag size.
|
||||
// Note that there is no padding by zeros in the overhead calculation.
|
||||
overheadSize int
|
||||
// readMutex guards against concurrent calls to Read. This is required since
|
||||
// Close may be called during a Read.
|
||||
readMutex sync.Mutex
|
||||
// writeMutex guards against concurrent calls to Write. This is required
|
||||
// since Close may be called during a Write, and also because a key update
|
||||
// message may be written during a Read.
|
||||
writeMutex sync.Mutex
|
||||
// handshakeBuf holds handshake messages while they are being processed.
|
||||
handshakeBuf []byte
|
||||
// ticketState is the current processing state of the session tickets.
|
||||
ticketState sessionTicketState
|
||||
// sessionTickets holds the completed session tickets until they are sent to
|
||||
// the handshaker service for processing.
|
||||
sessionTickets [][]byte
|
||||
// ticketSender sends session tickets to the S2A handshaker service.
|
||||
ticketSender s2aTicketSender
|
||||
// callComplete is a channel that blocks closing the record protocol until a
|
||||
// pending call to the S2A completes.
|
||||
callComplete chan bool
|
||||
}
|
||||
|
||||
// ConnParameters holds the parameters used for creating a new conn object.
|
||||
type ConnParameters struct {
|
||||
// NetConn is the TCP connection to the peer. This parameter is required.
|
||||
NetConn net.Conn
|
||||
// Ciphersuite is the TLS ciphersuite negotiated by the S2A handshaker
|
||||
// service. This parameter is required.
|
||||
Ciphersuite commonpb.Ciphersuite
|
||||
// TLSVersion is the TLS version number negotiated by the S2A handshaker
|
||||
// service. This parameter is required.
|
||||
TLSVersion commonpb.TLSVersion
|
||||
// InTrafficSecret is the traffic secret used to derive the session key for
|
||||
// the inbound direction. This parameter is required.
|
||||
InTrafficSecret []byte
|
||||
// OutTrafficSecret is the traffic secret used to derive the session key
|
||||
// for the outbound direction. This parameter is required.
|
||||
OutTrafficSecret []byte
|
||||
// UnusedBuf is the data read from the network that has not yet been
|
||||
// decrypted. This parameter is optional. If not provided, then no
|
||||
// application data was sent in the same flight of messages as the final
|
||||
// handshake message.
|
||||
UnusedBuf []byte
|
||||
// InSequence is the sequence number of the next, incoming, TLS record.
|
||||
// This parameter is required.
|
||||
InSequence uint64
|
||||
// OutSequence is the sequence number of the next, outgoing, TLS record.
|
||||
// This parameter is required.
|
||||
OutSequence uint64
|
||||
// HSAddr stores the address of the S2A handshaker service. This parameter
|
||||
// is optional. If not provided, then TLS resumption is disabled.
|
||||
HSAddr string
|
||||
// ConnectionId is the connection identifier that was created and sent by
|
||||
// S2A at the end of a handshake.
|
||||
ConnectionID uint64
|
||||
// LocalIdentity is the local identity that was used by S2A during session
|
||||
// setup and included in the session result.
|
||||
LocalIdentity *commonpb.Identity
|
||||
// EnsureProcessSessionTickets allows users to wait and ensure that all
|
||||
// available session tickets are sent to S2A before a process completes.
|
||||
EnsureProcessSessionTickets *sync.WaitGroup
|
||||
}
|
||||
|
||||
// NewConn creates a TLS record protocol that wraps the TCP connection.
|
||||
func NewConn(o *ConnParameters) (net.Conn, error) {
|
||||
if o == nil {
|
||||
return nil, errors.New("conn options must not be nil")
|
||||
}
|
||||
if o.TLSVersion != commonpb.TLSVersion_TLS1_3 {
|
||||
return nil, errors.New("TLS version must be TLS 1.3")
|
||||
}
|
||||
|
||||
inConn, err := halfconn.New(o.Ciphersuite, o.InTrafficSecret, o.InSequence)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create inbound half connection: %v", err)
|
||||
}
|
||||
outConn, err := halfconn.New(o.Ciphersuite, o.OutTrafficSecret, o.OutSequence)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create outbound half connection: %v", err)
|
||||
}
|
||||
|
||||
// The tag size for the in/out connections should be the same.
|
||||
overheadSize := tlsRecordHeaderSize + tlsRecordTypeSize + inConn.TagSize()
|
||||
var unusedBuf []byte
|
||||
if o.UnusedBuf == nil {
|
||||
// We pre-allocate unusedBuf to be of size
|
||||
// 2*tlsRecordMaxSize-1 during initialization. We only read from the
|
||||
// network into unusedBuf when unusedBuf does not contain a complete
|
||||
// record and the incomplete record is at most tlsRecordMaxSize-1
|
||||
// (bytes). And we read at most tlsRecordMaxSize bytes of data from the
|
||||
// network into unusedBuf at one time. Therefore, 2*tlsRecordMaxSize-1
|
||||
// is large enough to buffer data read from the network.
|
||||
unusedBuf = make([]byte, 0, 2*tlsRecordMaxSize-1)
|
||||
} else {
|
||||
unusedBuf = make([]byte, len(o.UnusedBuf))
|
||||
copy(unusedBuf, o.UnusedBuf)
|
||||
}
|
||||
|
||||
tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
if err != nil {
|
||||
grpclog.Infof("failed to create single token access token manager: %v", err)
|
||||
}
|
||||
|
||||
s2aConn := &conn{
|
||||
Conn: o.NetConn,
|
||||
inConn: inConn,
|
||||
outConn: outConn,
|
||||
unusedBuf: unusedBuf,
|
||||
outRecordsBuf: make([]byte, tlsRecordMaxSize),
|
||||
nextRecord: unusedBuf,
|
||||
overheadSize: overheadSize,
|
||||
ticketState: ticketsNotYetReceived,
|
||||
// Pre-allocate the buffer for one session ticket message and the max
|
||||
// plaintext size. This is the largest size that handshakeBuf will need
|
||||
// to hold. The largest incomplete handshake message is the
|
||||
// [handshake header size] + [max session ticket size] - 1.
|
||||
// Then, tlsRecordMaxPlaintextSize is the maximum size that will be
|
||||
// appended to the handshakeBuf before the handshake message is
|
||||
// completed. Therefore, the buffer size below should be large enough to
|
||||
// buffer any handshake messages.
|
||||
handshakeBuf: make([]byte, 0, tlsHandshakePrefixSize+tlsMaxSessionTicketSize+tlsRecordMaxPlaintextSize-1),
|
||||
ticketSender: &ticketSender{
|
||||
hsAddr: o.HSAddr,
|
||||
connectionID: o.ConnectionID,
|
||||
localIdentity: o.LocalIdentity,
|
||||
tokenManager: tokenManager,
|
||||
ensureProcessSessionTickets: o.EnsureProcessSessionTickets,
|
||||
},
|
||||
callComplete: make(chan bool),
|
||||
}
|
||||
return s2aConn, nil
|
||||
}
|
||||
|
||||
// Read reads and decrypts a TLS 1.3 record from the underlying connection, and
|
||||
// copies any application data received from the peer into b. If the size of the
|
||||
// payload is greater than len(b), Read retains the remaining bytes in an
|
||||
// internal buffer, and subsequent calls to Read will read from this buffer
|
||||
// until it is exhausted. At most 1 TLS record worth of application data is
|
||||
// written to b for each call to Read.
|
||||
//
|
||||
// Note that for the user to efficiently call this method, the user should
|
||||
// ensure that the buffer b is allocated such that the buffer does not have any
|
||||
// unused segments. This can be done by calling Read via io.ReadFull, which
|
||||
// continually calls Read until the specified buffer has been filled. Also note
|
||||
// that the user should close the connection via Close() if an error is thrown
|
||||
// by a call to Read.
|
||||
func (p *conn) Read(b []byte) (n int, err error) {
|
||||
p.readMutex.Lock()
|
||||
defer p.readMutex.Unlock()
|
||||
// Check if p.pendingApplication data has leftover application data from
|
||||
// the previous call to Read.
|
||||
if len(p.pendingApplicationData) == 0 {
|
||||
// Read a full record from the wire.
|
||||
record, err := p.readFullRecord()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Now we have a complete record, so split the header and validate it
|
||||
// The TLS record is split into 2 pieces: the record header and the
|
||||
// payload. The payload has the following form:
|
||||
// [payload] = [ciphertext of application data]
|
||||
// + [ciphertext of record type byte]
|
||||
// + [(optionally) ciphertext of padding by zeros]
|
||||
// + [tag]
|
||||
header, payload, err := splitAndValidateHeader(record)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Decrypt the ciphertext.
|
||||
p.pendingApplicationData, err = p.inConn.Decrypt(payload[:0], payload, header)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Remove the padding by zeros and the record type byte from the
|
||||
// p.pendingApplicationData buffer.
|
||||
msgType, err := p.stripPaddingAndType()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Check that the length of the plaintext after stripping the padding
|
||||
// and record type byte is under the maximum plaintext size.
|
||||
if len(p.pendingApplicationData) > tlsRecordMaxPlaintextSize {
|
||||
return 0, errors.New("plaintext size larger than maximum")
|
||||
}
|
||||
// The expected message types are application data, alert, and
|
||||
// handshake. For application data, the bytes are directly copied into
|
||||
// b. For an alert, the type of the alert is checked and the connection
|
||||
// is closed on a close notify alert. For a handshake message, the
|
||||
// handshake message type is checked. The handshake message type can be
|
||||
// a key update type, for which we advance the traffic secret, and a
|
||||
// new session ticket type, for which we send the received ticket to S2A
|
||||
// for processing.
|
||||
switch msgType {
|
||||
case applicationData:
|
||||
if len(p.handshakeBuf) > 0 {
|
||||
return 0, errors.New("application data received while processing fragmented handshake messages")
|
||||
}
|
||||
if p.ticketState == receivingTickets {
|
||||
p.ticketState = notReceivingTickets
|
||||
grpclog.Infof("Sending session tickets to S2A.")
|
||||
p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete)
|
||||
}
|
||||
case alert:
|
||||
return 0, p.handleAlertMessage()
|
||||
case handshake:
|
||||
if err = p.handleHandshakeMessage(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return 0, nil
|
||||
default:
|
||||
return 0, errors.New("unknown record type")
|
||||
}
|
||||
}
|
||||
// Write as much application data as possible to b, the output buffer.
|
||||
n = copy(b, p.pendingApplicationData)
|
||||
p.pendingApplicationData = p.pendingApplicationData[n:]
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Write divides b into segments of size tlsRecordMaxPlaintextSize, builds a
|
||||
// TLS 1.3 record (of type "application data") from each segment, and sends
|
||||
// the record to the peer. It returns the number of plaintext bytes that were
|
||||
// successfully sent to the peer.
|
||||
func (p *conn) Write(b []byte) (n int, err error) {
|
||||
p.writeMutex.Lock()
|
||||
defer p.writeMutex.Unlock()
|
||||
return p.writeTLSRecord(b, tlsApplicationData)
|
||||
}
|
||||
|
||||
// writeTLSRecord divides b into segments of size maxPlaintextBytesPerRecord,
|
||||
// builds a TLS 1.3 record (of type recordType) from each segment, and sends
|
||||
// the record to the peer. It returns the number of plaintext bytes that were
|
||||
// successfully sent to the peer.
|
||||
func (p *conn) writeTLSRecord(b []byte, recordType byte) (n int, err error) {
|
||||
// Create a record of only header, record type, and tag if given empty
|
||||
// byte array.
|
||||
if len(b) == 0 {
|
||||
recordEndIndex, _, err := p.buildRecord(b, recordType, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Write the bytes stored in outRecordsBuf to p.Conn. Since we return
|
||||
// the number of plaintext bytes written without overhead, we will
|
||||
// always return 0 while p.Conn.Write returns the entire record length.
|
||||
_, err = p.Conn.Write(p.outRecordsBuf[:recordEndIndex])
|
||||
return 0, err
|
||||
}
|
||||
|
||||
numRecords := int(math.Ceil(float64(len(b)) / float64(tlsRecordMaxPlaintextSize)))
|
||||
totalRecordsSize := len(b) + numRecords*p.overheadSize
|
||||
partialBSize := len(b)
|
||||
if totalRecordsSize > outBufMaxSize {
|
||||
totalRecordsSize = outBufMaxSize
|
||||
partialBSize = outBufMaxRecords * tlsRecordMaxPlaintextSize
|
||||
}
|
||||
if len(p.outRecordsBuf) < totalRecordsSize {
|
||||
p.outRecordsBuf = make([]byte, totalRecordsSize)
|
||||
}
|
||||
for bStart := 0; bStart < len(b); bStart += partialBSize {
|
||||
bEnd := bStart + partialBSize
|
||||
if bEnd > len(b) {
|
||||
bEnd = len(b)
|
||||
}
|
||||
partialB := b[bStart:bEnd]
|
||||
recordEndIndex := 0
|
||||
for len(partialB) > 0 {
|
||||
recordEndIndex, partialB, err = p.buildRecord(partialB, recordType, recordEndIndex)
|
||||
if err != nil {
|
||||
// Return the amount of bytes written prior to the error.
|
||||
return bStart, err
|
||||
}
|
||||
}
|
||||
// Write the bytes stored in outRecordsBuf to p.Conn. If there is an
|
||||
// error, calculate the total number of plaintext bytes of complete
|
||||
// records successfully written to the peer and return it.
|
||||
nn, err := p.Conn.Write(p.outRecordsBuf[:recordEndIndex])
|
||||
if err != nil {
|
||||
numberOfCompletedRecords := int(math.Floor(float64(nn) / float64(tlsRecordMaxSize)))
|
||||
return bStart + numberOfCompletedRecords*tlsRecordMaxPlaintextSize, err
|
||||
}
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// buildRecord builds a TLS 1.3 record of type recordType from plaintext,
|
||||
// and writes the record to outRecordsBuf at recordStartIndex. The record will
|
||||
// have at most tlsRecordMaxPlaintextSize bytes of payload. It returns the
|
||||
// index of outRecordsBuf where the current record ends, as well as any
|
||||
// remaining plaintext bytes.
|
||||
func (p *conn) buildRecord(plaintext []byte, recordType byte, recordStartIndex int) (n int, remainingPlaintext []byte, err error) {
|
||||
// Construct the payload, which consists of application data and record type.
|
||||
dataLen := len(plaintext)
|
||||
if dataLen > tlsRecordMaxPlaintextSize {
|
||||
dataLen = tlsRecordMaxPlaintextSize
|
||||
}
|
||||
remainingPlaintext = plaintext[dataLen:]
|
||||
newRecordBuf := p.outRecordsBuf[recordStartIndex:]
|
||||
|
||||
copy(newRecordBuf[tlsRecordHeaderSize:], plaintext[:dataLen])
|
||||
newRecordBuf[tlsRecordHeaderSize+dataLen] = recordType
|
||||
payload := newRecordBuf[tlsRecordHeaderSize : tlsRecordHeaderSize+dataLen+1] // 1 is for the recordType.
|
||||
// Construct the header.
|
||||
newRecordBuf[0] = tlsApplicationData
|
||||
newRecordBuf[1] = tlsLegacyRecordVersion
|
||||
newRecordBuf[2] = tlsLegacyRecordVersion
|
||||
binary.BigEndian.PutUint16(newRecordBuf[3:], uint16(len(payload)+tlsTagSize))
|
||||
header := newRecordBuf[:tlsRecordHeaderSize]
|
||||
|
||||
// Encrypt the payload using header as aad.
|
||||
encryptedPayload, err := p.outConn.Encrypt(newRecordBuf[tlsRecordHeaderSize:][:0], payload, header)
|
||||
if err != nil {
|
||||
return 0, plaintext, err
|
||||
}
|
||||
recordStartIndex += len(header) + len(encryptedPayload)
|
||||
return recordStartIndex, remainingPlaintext, nil
|
||||
}
|
||||
|
||||
func (p *conn) Close() error {
|
||||
p.readMutex.Lock()
|
||||
defer p.readMutex.Unlock()
|
||||
p.writeMutex.Lock()
|
||||
defer p.writeMutex.Unlock()
|
||||
// If p.ticketState is equal to notReceivingTickets, then S2A has
|
||||
// been sent a flight of session tickets, and we must wait for the
|
||||
// call to S2A to complete before closing the record protocol.
|
||||
if p.ticketState == notReceivingTickets {
|
||||
<-p.callComplete
|
||||
grpclog.Infof("Safe to close the connection because sending tickets to S2A is (already) complete.")
|
||||
}
|
||||
return p.Conn.Close()
|
||||
}
|
||||
|
||||
// stripPaddingAndType strips the padding by zeros and record type from
|
||||
// p.pendingApplicationData and returns the record type. Note that
|
||||
// p.pendingApplicationData should be of the form:
|
||||
// [application data] + [record type byte] + [trailing zeros]
|
||||
func (p *conn) stripPaddingAndType() (recordType, error) {
|
||||
if len(p.pendingApplicationData) == 0 {
|
||||
return 0, errors.New("application data had length 0")
|
||||
}
|
||||
i := len(p.pendingApplicationData) - 1
|
||||
// Search for the index of the record type byte.
|
||||
for i > 0 {
|
||||
if p.pendingApplicationData[i] != 0 {
|
||||
break
|
||||
}
|
||||
i--
|
||||
}
|
||||
rt := recordType(p.pendingApplicationData[i])
|
||||
p.pendingApplicationData = p.pendingApplicationData[:i]
|
||||
return rt, nil
|
||||
}
|
||||
|
||||
// readFullRecord reads from the wire until a record is completed and returns
|
||||
// the full record.
|
||||
func (p *conn) readFullRecord() (fullRecord []byte, err error) {
|
||||
fullRecord, p.nextRecord, err = parseReadBuffer(p.nextRecord, tlsRecordMaxPayloadSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Check whether the next record to be decrypted has been completely
|
||||
// received.
|
||||
if len(fullRecord) == 0 {
|
||||
copy(p.unusedBuf, p.nextRecord)
|
||||
p.unusedBuf = p.unusedBuf[:len(p.nextRecord)]
|
||||
// Always copy next incomplete record to the beginning of the
|
||||
// unusedBuf buffer and reset nextRecord to it.
|
||||
p.nextRecord = p.unusedBuf
|
||||
}
|
||||
// Keep reading from the wire until we have a complete record.
|
||||
for len(fullRecord) == 0 {
|
||||
if len(p.unusedBuf) == cap(p.unusedBuf) {
|
||||
tmp := make([]byte, len(p.unusedBuf), cap(p.unusedBuf)+tlsRecordMaxSize)
|
||||
copy(tmp, p.unusedBuf)
|
||||
p.unusedBuf = tmp
|
||||
}
|
||||
n, err := p.Conn.Read(p.unusedBuf[len(p.unusedBuf):min(cap(p.unusedBuf), len(p.unusedBuf)+tlsRecordMaxSize)])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.unusedBuf = p.unusedBuf[:len(p.unusedBuf)+n]
|
||||
fullRecord, p.nextRecord, err = parseReadBuffer(p.unusedBuf, tlsRecordMaxPayloadSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return fullRecord, nil
|
||||
}
|
||||
|
||||
// parseReadBuffer parses the provided buffer and returns a full record and any
|
||||
// remaining bytes in that buffer. If the record is incomplete, nil is returned
|
||||
// for the first return value and the given byte buffer is returned for the
|
||||
// second return value. The length of the payload specified by the header should
|
||||
// not be greater than maxLen, otherwise an error is returned. Note that this
|
||||
// function does not allocate or copy any buffers.
|
||||
func parseReadBuffer(b []byte, maxLen uint16) (fullRecord, remaining []byte, err error) {
|
||||
// If the header is not complete, return the provided buffer as remaining
|
||||
// buffer.
|
||||
if len(b) < tlsRecordHeaderSize {
|
||||
return nil, b, nil
|
||||
}
|
||||
msgLenField := b[tlsRecordHeaderTypeSize+tlsRecordHeaderLegacyRecordVersionSize : tlsRecordHeaderSize]
|
||||
length := binary.BigEndian.Uint16(msgLenField)
|
||||
if length > maxLen {
|
||||
return nil, nil, fmt.Errorf("record length larger than the limit %d", maxLen)
|
||||
}
|
||||
if len(b) < int(length)+tlsRecordHeaderSize {
|
||||
// Record is not complete yet.
|
||||
return nil, b, nil
|
||||
}
|
||||
return b[:tlsRecordHeaderSize+length], b[tlsRecordHeaderSize+length:], nil
|
||||
}
|
||||
|
||||
// splitAndValidateHeader splits the header from the payload in the TLS 1.3
|
||||
// record and returns them. Note that the header is checked for validity, and an
|
||||
// error is returned when an invalid header is parsed. Also note that this
|
||||
// function does not allocate or copy any buffers.
|
||||
func splitAndValidateHeader(record []byte) (header, payload []byte, err error) {
|
||||
if len(record) < tlsRecordHeaderSize {
|
||||
return nil, nil, fmt.Errorf("record was smaller than the header size")
|
||||
}
|
||||
header = record[:tlsRecordHeaderSize]
|
||||
payload = record[tlsRecordHeaderSize:]
|
||||
if header[0] != tlsApplicationData {
|
||||
return nil, nil, fmt.Errorf("incorrect type in the header")
|
||||
}
|
||||
// Check the legacy record version, which should be 0x03, 0x03.
|
||||
if header[1] != 0x03 || header[2] != 0x03 {
|
||||
return nil, nil, fmt.Errorf("incorrect legacy record version in the header")
|
||||
}
|
||||
return header, payload, nil
|
||||
}
|
||||
|
||||
// handleAlertMessage handles an alert message.
|
||||
func (p *conn) handleAlertMessage() error {
|
||||
if len(p.pendingApplicationData) != tlsAlertSize {
|
||||
return errors.New("invalid alert message size")
|
||||
}
|
||||
alertType := p.pendingApplicationData[1]
|
||||
// Clear the body of the alert message.
|
||||
p.pendingApplicationData = p.pendingApplicationData[:0]
|
||||
if alertType == byte(closeNotify) {
|
||||
return errors.New("received a close notify alert")
|
||||
}
|
||||
// TODO(matthewstevenson88): Add support for more alert types.
|
||||
return fmt.Errorf("received an unrecognized alert type: %v", alertType)
|
||||
}
|
||||
|
||||
// parseHandshakeHeader parses a handshake message from the handshake buffer.
|
||||
// It returns the message type, the message length, the message, the raw message
|
||||
// that includes the type and length bytes and a flag indicating whether the
|
||||
// handshake message has been fully parsed. i.e. whether the entire handshake
|
||||
// message was in the handshake buffer.
|
||||
func (p *conn) parseHandshakeMsg() (msgType byte, msgLen uint32, msg []byte, rawMsg []byte, ok bool) {
|
||||
// Handle the case where the 4 byte handshake header is fragmented.
|
||||
if len(p.handshakeBuf) < tlsHandshakePrefixSize {
|
||||
return 0, 0, nil, nil, false
|
||||
}
|
||||
msgType = p.handshakeBuf[0]
|
||||
msgLen = bigEndianInt24(p.handshakeBuf[tlsHandshakeMsgTypeSize : tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize])
|
||||
if msgLen > uint32(len(p.handshakeBuf)-tlsHandshakePrefixSize) {
|
||||
return 0, 0, nil, nil, false
|
||||
}
|
||||
msg = p.handshakeBuf[tlsHandshakePrefixSize : tlsHandshakePrefixSize+msgLen]
|
||||
rawMsg = p.handshakeBuf[:tlsHandshakeMsgTypeSize+tlsHandshakeLengthSize+msgLen]
|
||||
p.handshakeBuf = p.handshakeBuf[tlsHandshakePrefixSize+msgLen:]
|
||||
return msgType, msgLen, msg, rawMsg, true
|
||||
}
|
||||
|
||||
// handleHandshakeMessage handles a handshake message. Note that the first
|
||||
// complete handshake message from the handshake buffer is removed, if it
|
||||
// exists.
|
||||
func (p *conn) handleHandshakeMessage() error {
|
||||
// Copy the pending application data to the handshake buffer. At this point,
|
||||
// we are guaranteed that the pending application data contains only parts
|
||||
// of a handshake message.
|
||||
p.handshakeBuf = append(p.handshakeBuf, p.pendingApplicationData...)
|
||||
p.pendingApplicationData = p.pendingApplicationData[:0]
|
||||
// Several handshake messages may be coalesced into a single record.
|
||||
// Continue reading them until the handshake buffer is empty.
|
||||
for len(p.handshakeBuf) > 0 {
|
||||
handshakeMsgType, msgLen, msg, rawMsg, ok := p.parseHandshakeMsg()
|
||||
if !ok {
|
||||
// The handshake could not be fully parsed, so read in another
|
||||
// record and try again later.
|
||||
break
|
||||
}
|
||||
switch handshakeMsgType {
|
||||
case tlsHandshakeKeyUpdateType:
|
||||
if msgLen != tlsHandshakeKeyUpdateMsgSize {
|
||||
return errors.New("invalid handshake key update message length")
|
||||
}
|
||||
if len(p.handshakeBuf) != 0 {
|
||||
return errors.New("key update message must be the last message of a handshake record")
|
||||
}
|
||||
if err := p.handleKeyUpdateMsg(msg); err != nil {
|
||||
return err
|
||||
}
|
||||
case tlsHandshakeNewSessionTicketType:
|
||||
// Ignore tickets that are received after a batch of tickets has
|
||||
// been sent to S2A.
|
||||
if p.ticketState == notReceivingTickets {
|
||||
continue
|
||||
}
|
||||
if p.ticketState == ticketsNotYetReceived {
|
||||
p.ticketState = receivingTickets
|
||||
}
|
||||
p.sessionTickets = append(p.sessionTickets, rawMsg)
|
||||
if len(p.sessionTickets) == maxAllowedTickets {
|
||||
p.ticketState = notReceivingTickets
|
||||
grpclog.Infof("Sending session tickets to S2A.")
|
||||
p.ticketSender.sendTicketsToS2A(p.sessionTickets, p.callComplete)
|
||||
}
|
||||
default:
|
||||
return errors.New("unknown handshake message type")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildKeyUpdateRequest() []byte {
|
||||
b := make([]byte, tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize)
|
||||
b[0] = tlsHandshakeKeyUpdateType
|
||||
b[1] = 0
|
||||
b[2] = 0
|
||||
b[3] = tlsHandshakeKeyUpdateMsgSize
|
||||
b[4] = byte(updateNotRequested)
|
||||
return b
|
||||
}
|
||||
|
||||
// handleKeyUpdateMsg handles a key update message.
|
||||
func (p *conn) handleKeyUpdateMsg(msg []byte) error {
|
||||
keyUpdateRequest := msg[0]
|
||||
if keyUpdateRequest != byte(updateNotRequested) &&
|
||||
keyUpdateRequest != byte(updateRequested) {
|
||||
return errors.New("invalid handshake key update message")
|
||||
}
|
||||
if err := p.inConn.UpdateKey(); err != nil {
|
||||
return err
|
||||
}
|
||||
// Send a key update message back to the peer if requested.
|
||||
if keyUpdateRequest == byte(updateRequested) {
|
||||
p.writeMutex.Lock()
|
||||
defer p.writeMutex.Unlock()
|
||||
n, err := p.writeTLSRecord(preConstructedKeyUpdateMsg, byte(handshake))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != tlsHandshakePrefixSize+tlsHandshakeKeyUpdateMsgSize {
|
||||
return errors.New("key update request message wrote less bytes than expected")
|
||||
}
|
||||
if err = p.outConn.UpdateKey(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bidEndianInt24 converts the given byte buffer of at least size 3 and
|
||||
// outputs the resulting 24 bit integer as a uint32. This is needed because
|
||||
// TLS 1.3 requires 3 byte integers, and the binary.BigEndian package does
|
||||
// not provide a way to transform a byte buffer into a 3 byte integer.
|
||||
func bigEndianInt24(b []byte) uint32 {
|
||||
_ = b[2] // bounds check hint to compiler; see golang.org/issue/14808
|
||||
return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
176
vendor/github.com/google/s2a-go/internal/record/ticketsender.go
generated
vendored
Normal file
176
vendor/github.com/google/s2a-go/internal/record/ticketsender.go
generated
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 record
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/s2a-go/internal/handshaker/service"
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
s2apb "github.com/google/s2a-go/internal/proto/s2a_go_proto"
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
)
|
||||
|
||||
// sessionTimeout is the timeout for creating a session with the S2A handshaker
|
||||
// service.
|
||||
const sessionTimeout = time.Second * 5
|
||||
|
||||
// s2aTicketSender sends session tickets to the S2A handshaker service.
|
||||
type s2aTicketSender interface {
|
||||
// sendTicketsToS2A sends the given session tickets to the S2A handshaker
|
||||
// service.
|
||||
sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool)
|
||||
}
|
||||
|
||||
// ticketStream is the stream used to send and receive session information.
|
||||
type ticketStream interface {
|
||||
Send(*s2apb.SessionReq) error
|
||||
Recv() (*s2apb.SessionResp, error)
|
||||
}
|
||||
|
||||
type ticketSender struct {
|
||||
// hsAddr stores the address of the S2A handshaker service.
|
||||
hsAddr string
|
||||
// connectionID is the connection identifier that was created and sent by
|
||||
// S2A at the end of a handshake.
|
||||
connectionID uint64
|
||||
// localIdentity is the local identity that was used by S2A during session
|
||||
// setup and included in the session result.
|
||||
localIdentity *commonpb.Identity
|
||||
// tokenManager manages access tokens for authenticating to S2A.
|
||||
tokenManager tokenmanager.AccessTokenManager
|
||||
// ensureProcessSessionTickets allows users to wait and ensure that all
|
||||
// available session tickets are sent to S2A before a process completes.
|
||||
ensureProcessSessionTickets *sync.WaitGroup
|
||||
}
|
||||
|
||||
// sendTicketsToS2A sends the given sessionTickets to the S2A handshaker
|
||||
// service. This is done asynchronously and writes to the error logs if an error
|
||||
// occurs.
|
||||
func (t *ticketSender) sendTicketsToS2A(sessionTickets [][]byte, callComplete chan bool) {
|
||||
// Note that the goroutine is in the function rather than at the caller
|
||||
// because the fake ticket sender used for testing must run synchronously
|
||||
// so that the session tickets can be accessed from it after the tests have
|
||||
// been run.
|
||||
if t.ensureProcessSessionTickets != nil {
|
||||
t.ensureProcessSessionTickets.Add(1)
|
||||
}
|
||||
go func() {
|
||||
if err := func() error {
|
||||
defer func() {
|
||||
if t.ensureProcessSessionTickets != nil {
|
||||
t.ensureProcessSessionTickets.Done()
|
||||
}
|
||||
}()
|
||||
hsConn, err := service.Dial(t.hsAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := s2apb.NewS2AServiceClient(hsConn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), sessionTimeout)
|
||||
defer cancel()
|
||||
session, err := client.SetUpSession(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := session.CloseSend(); err != nil {
|
||||
grpclog.Error(err)
|
||||
}
|
||||
}()
|
||||
return t.writeTicketsToStream(session, sessionTickets)
|
||||
}(); err != nil {
|
||||
grpclog.Errorf("failed to send resumption tickets to S2A with identity: %v, %v",
|
||||
t.localIdentity, err)
|
||||
}
|
||||
callComplete <- true
|
||||
close(callComplete)
|
||||
}()
|
||||
}
|
||||
|
||||
// writeTicketsToStream writes the given session tickets to the given stream.
|
||||
func (t *ticketSender) writeTicketsToStream(stream ticketStream, sessionTickets [][]byte) error {
|
||||
if err := stream.Send(
|
||||
&s2apb.SessionReq{
|
||||
ReqOneof: &s2apb.SessionReq_ResumptionTicket{
|
||||
ResumptionTicket: &s2apb.ResumptionTicketReq{
|
||||
InBytes: sessionTickets,
|
||||
ConnectionId: t.connectionID,
|
||||
LocalIdentity: t.localIdentity,
|
||||
},
|
||||
},
|
||||
AuthMechanisms: t.getAuthMechanisms(),
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
sessionResp, err := stream.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sessionResp.GetStatus().GetCode() != uint32(codes.OK) {
|
||||
return fmt.Errorf("s2a session ticket response had error status: %v, %v",
|
||||
sessionResp.GetStatus().GetCode(), sessionResp.GetStatus().GetDetails())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ticketSender) getAuthMechanisms() []*s2apb.AuthenticationMechanism {
|
||||
if t.tokenManager == nil {
|
||||
return nil
|
||||
}
|
||||
// First handle the special case when no local identity has been provided
|
||||
// by the application. In this case, an AuthenticationMechanism with no local
|
||||
// identity will be sent.
|
||||
if t.localIdentity == nil {
|
||||
token, err := t.tokenManager.DefaultToken()
|
||||
if err != nil {
|
||||
grpclog.Infof("unable to get token for empty local identity: %v", err)
|
||||
return nil
|
||||
}
|
||||
return []*s2apb.AuthenticationMechanism{
|
||||
{
|
||||
MechanismOneof: &s2apb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Next, handle the case where the application (or the S2A) has specified
|
||||
// a local identity.
|
||||
token, err := t.tokenManager.Token(t.localIdentity)
|
||||
if err != nil {
|
||||
grpclog.Infof("unable to get token for local identity %v: %v", t.localIdentity, err)
|
||||
return nil
|
||||
}
|
||||
return []*s2apb.AuthenticationMechanism{
|
||||
{
|
||||
Identity: t.localIdentity,
|
||||
MechanismOneof: &s2apb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
70
vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go
generated
vendored
Normal file
70
vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 tokenmanager provides tokens for authenticating to S2A.
|
||||
package tokenmanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
)
|
||||
|
||||
const (
|
||||
s2aAccessTokenEnvironmentVariable = "S2A_ACCESS_TOKEN"
|
||||
)
|
||||
|
||||
// AccessTokenManager manages tokens for authenticating to S2A.
|
||||
type AccessTokenManager interface {
|
||||
// DefaultToken returns a token that an application with no specified local
|
||||
// identity must use to authenticate to S2A.
|
||||
DefaultToken() (token string, err error)
|
||||
// Token returns a token that an application with local identity equal to
|
||||
// identity must use to authenticate to S2A.
|
||||
Token(identity *commonpb.Identity) (token string, err error)
|
||||
}
|
||||
|
||||
type singleTokenAccessTokenManager struct {
|
||||
token string
|
||||
}
|
||||
|
||||
// NewSingleTokenAccessTokenManager returns a new AccessTokenManager instance
|
||||
// that will always manage the same token.
|
||||
//
|
||||
// The token to be managed is read from the s2aAccessTokenEnvironmentVariable
|
||||
// environment variable. If this environment variable is not set, then this
|
||||
// function returns an error.
|
||||
func NewSingleTokenAccessTokenManager() (AccessTokenManager, error) {
|
||||
token, variableExists := os.LookupEnv(s2aAccessTokenEnvironmentVariable)
|
||||
if !variableExists {
|
||||
return nil, fmt.Errorf("%s environment variable is not set", s2aAccessTokenEnvironmentVariable)
|
||||
}
|
||||
return &singleTokenAccessTokenManager{token: token}, nil
|
||||
}
|
||||
|
||||
// DefaultToken always returns the token managed by the
|
||||
// singleTokenAccessTokenManager.
|
||||
func (m *singleTokenAccessTokenManager) DefaultToken() (string, error) {
|
||||
return m.token, nil
|
||||
}
|
||||
|
||||
// Token always returns the token managed by the singleTokenAccessTokenManager.
|
||||
func (m *singleTokenAccessTokenManager) Token(*commonpb.Identity) (string, error) {
|
||||
return m.token, nil
|
||||
}
|
||||
1
vendor/github.com/google/s2a-go/internal/v2/README.md
generated
vendored
Normal file
1
vendor/github.com/google/s2a-go/internal/v2/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
**This directory has the implementation of the S2Av2's gRPC-Go client libraries**
|
||||
120
vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go
generated
vendored
Normal file
120
vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go
generated
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 certverifier offloads verifications to S2Av2.
|
||||
package certverifier
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
|
||||
)
|
||||
|
||||
// VerifyClientCertificateChain builds a SessionReq, sends it to S2Av2 and
|
||||
// receives a SessionResp.
|
||||
func VerifyClientCertificateChain(verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, cstream s2av2pb.S2AService_SetUpSessionClient) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
// Offload verification to S2Av2.
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Sending request to S2Av2 for client peer cert chain validation.")
|
||||
}
|
||||
if err := cstream.Send(&s2av2pb.SessionReq{
|
||||
ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{
|
||||
ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{
|
||||
Mode: verificationMode,
|
||||
PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer_{
|
||||
ClientPeer: &s2av2pb.ValidatePeerCertificateChainReq_ClientPeer{
|
||||
CertificateChain: rawCerts,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
grpclog.Infof("Failed to send request to S2Av2 for client peer cert chain validation.")
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the response from S2Av2.
|
||||
resp, err := cstream.Recv()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to receive client peer cert chain validation response from S2Av2.")
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse the response.
|
||||
if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
|
||||
return fmt.Errorf("failed to offload client cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
|
||||
|
||||
}
|
||||
|
||||
if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS {
|
||||
return fmt.Errorf("client cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyServerCertificateChain builds a SessionReq, sends it to S2Av2 and
|
||||
// receives a SessionResp.
|
||||
func VerifyServerCertificateChain(hostname string, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, cstream s2av2pb.S2AService_SetUpSessionClient) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
// Offload verification to S2Av2.
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Sending request to S2Av2 for server peer cert chain validation.")
|
||||
}
|
||||
if err := cstream.Send(&s2av2pb.SessionReq{
|
||||
ReqOneof: &s2av2pb.SessionReq_ValidatePeerCertificateChainReq{
|
||||
ValidatePeerCertificateChainReq: &s2av2pb.ValidatePeerCertificateChainReq{
|
||||
Mode: verificationMode,
|
||||
PeerOneof: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer_{
|
||||
ServerPeer: &s2av2pb.ValidatePeerCertificateChainReq_ServerPeer{
|
||||
CertificateChain: rawCerts,
|
||||
ServerHostname: hostname,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
grpclog.Infof("Failed to send request to S2Av2 for server peer cert chain validation.")
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the response from S2Av2.
|
||||
resp, err := cstream.Recv()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to receive server peer cert chain validation response from S2Av2.")
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse the response.
|
||||
if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
|
||||
return fmt.Errorf("failed to offload server cert verification to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
|
||||
}
|
||||
|
||||
if resp.GetValidatePeerCertificateChainResp().ValidationResult != s2av2pb.ValidatePeerCertificateChainResp_SUCCESS {
|
||||
return fmt.Errorf("server cert verification failed: %v", resp.GetValidatePeerCertificateChainResp().ValidationDetails)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_intermediate_cert.der
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_leaf_cert.der
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/client_root_cert.der
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_intermediate_cert.der
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_leaf_cert.der
generated
vendored
Normal file
Binary file not shown.
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/certverifier/testdata/server_root_cert.der
generated
vendored
Normal file
Binary file not shown.
185
vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go
generated
vendored
Normal file
185
vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go
generated
vendored
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 remotesigner offloads private key operations to S2Av2.
|
||||
package remotesigner
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
|
||||
)
|
||||
|
||||
// remoteSigner implementes the crypto.Signer interface.
|
||||
type remoteSigner struct {
|
||||
leafCert *x509.Certificate
|
||||
cstream s2av2pb.S2AService_SetUpSessionClient
|
||||
}
|
||||
|
||||
// New returns an instance of RemoteSigner, an implementation of the
|
||||
// crypto.Signer interface.
|
||||
func New(leafCert *x509.Certificate, cstream s2av2pb.S2AService_SetUpSessionClient) crypto.Signer {
|
||||
return &remoteSigner{leafCert, cstream}
|
||||
}
|
||||
|
||||
func (s *remoteSigner) Public() crypto.PublicKey {
|
||||
return s.leafCert.PublicKey
|
||||
}
|
||||
|
||||
func (s *remoteSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||
signatureAlgorithm, err := getSignatureAlgorithm(opts, s.leafCert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := getSignReq(signatureAlgorithm, digest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Sending request to S2Av2 for signing operation.")
|
||||
}
|
||||
if err := s.cstream.Send(&s2av2pb.SessionReq{
|
||||
ReqOneof: &s2av2pb.SessionReq_OffloadPrivateKeyOperationReq{
|
||||
OffloadPrivateKeyOperationReq: req,
|
||||
},
|
||||
}); err != nil {
|
||||
grpclog.Infof("Failed to send request to S2Av2 for signing operation.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.cstream.Recv()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to receive signing operation response from S2Av2.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
|
||||
return nil, fmt.Errorf("failed to offload signing with private key to S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
|
||||
}
|
||||
|
||||
return resp.GetOffloadPrivateKeyOperationResp().GetOutBytes(), nil
|
||||
}
|
||||
|
||||
// getCert returns the leafCert field in s.
|
||||
func (s *remoteSigner) getCert() *x509.Certificate {
|
||||
return s.leafCert
|
||||
}
|
||||
|
||||
// getStream returns the cstream field in s.
|
||||
func (s *remoteSigner) getStream() s2av2pb.S2AService_SetUpSessionClient {
|
||||
return s.cstream
|
||||
}
|
||||
|
||||
func getSignReq(signatureAlgorithm s2av2pb.SignatureAlgorithm, digest []byte) (*s2av2pb.OffloadPrivateKeyOperationReq, error) {
|
||||
if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256) {
|
||||
return &s2av2pb.OffloadPrivateKeyOperationReq{
|
||||
Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
|
||||
SignatureAlgorithm: signatureAlgorithm,
|
||||
InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha256Digest{
|
||||
Sha256Digest: digest,
|
||||
},
|
||||
}, nil
|
||||
} else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384) {
|
||||
return &s2av2pb.OffloadPrivateKeyOperationReq{
|
||||
Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
|
||||
SignatureAlgorithm: signatureAlgorithm,
|
||||
InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha384Digest{
|
||||
Sha384Digest: digest,
|
||||
},
|
||||
}, nil
|
||||
} else if (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512) || (signatureAlgorithm == s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519) {
|
||||
return &s2av2pb.OffloadPrivateKeyOperationReq{
|
||||
Operation: s2av2pb.OffloadPrivateKeyOperationReq_SIGN,
|
||||
SignatureAlgorithm: signatureAlgorithm,
|
||||
InBytes: &s2av2pb.OffloadPrivateKeyOperationReq_Sha512Digest{
|
||||
Sha512Digest: digest,
|
||||
},
|
||||
}, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown signature algorithm: %v", signatureAlgorithm)
|
||||
}
|
||||
}
|
||||
|
||||
// getSignatureAlgorithm returns the signature algorithm that S2A must use when
|
||||
// performing a signing operation that has been offloaded by an application
|
||||
// using the crypto/tls libraries.
|
||||
func getSignatureAlgorithm(opts crypto.SignerOpts, leafCert *x509.Certificate) (s2av2pb.SignatureAlgorithm, error) {
|
||||
if opts == nil || leafCert == nil {
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
|
||||
}
|
||||
switch leafCert.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
if rsaPSSOpts, ok := opts.(*rsa.PSSOptions); ok {
|
||||
return rsaPSSAlgorithm(rsaPSSOpts)
|
||||
}
|
||||
return rsaPPKCS1Algorithm(opts)
|
||||
case x509.ECDSA:
|
||||
return ecdsaAlgorithm(opts)
|
||||
case x509.Ed25519:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ED25519, nil
|
||||
default:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm: %q", leafCert.PublicKeyAlgorithm)
|
||||
}
|
||||
}
|
||||
|
||||
func rsaPSSAlgorithm(opts *rsa.PSSOptions) (s2av2pb.SignatureAlgorithm, error) {
|
||||
switch opts.HashFunc() {
|
||||
case crypto.SHA256:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA256, nil
|
||||
case crypto.SHA384:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA384, nil
|
||||
case crypto.SHA512:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PSS_RSAE_SHA512, nil
|
||||
default:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func rsaPPKCS1Algorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
|
||||
switch opts.HashFunc() {
|
||||
case crypto.SHA256:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA256, nil
|
||||
case crypto.SHA384:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA384, nil
|
||||
case crypto.SHA512:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_RSA_PKCS1_SHA512, nil
|
||||
default:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func ecdsaAlgorithm(opts crypto.SignerOpts) (s2av2pb.SignatureAlgorithm, error) {
|
||||
switch opts.HashFunc() {
|
||||
case crypto.SHA256:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP256R1_SHA256, nil
|
||||
case crypto.SHA384:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP384R1_SHA384, nil
|
||||
case crypto.SHA512:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_ECDSA_SECP521R1_SHA512, nil
|
||||
default:
|
||||
return s2av2pb.SignatureAlgorithm_S2A_SSL_SIGN_UNSPECIFIED, fmt.Errorf("unknown signature algorithm")
|
||||
}
|
||||
}
|
||||
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der
generated
vendored
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.der
generated
vendored
Normal file
Binary file not shown.
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/client_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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
Normal file
BIN
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.der
generated
vendored
Normal file
Binary file not shown.
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/remotesigner/testdata/server_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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-----
|
||||
311
vendor/github.com/google/s2a-go/internal/v2/s2av2.go
generated
vendored
Normal file
311
vendor/github.com/google/s2a-go/internal/v2/s2av2.go
generated
vendored
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 v2 provides the S2Av2 transport credentials used by a gRPC
|
||||
// application.
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"flag"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/google/s2a-go/fallback"
|
||||
"github.com/google/s2a-go/internal/handshaker/service"
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
"github.com/google/s2a-go/internal/v2/tlsconfigstore"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
|
||||
)
|
||||
|
||||
const (
|
||||
s2aSecurityProtocol = "tls"
|
||||
)
|
||||
|
||||
var S2ATimeout = flag.Duration("s2a_timeout", 3*time.Second, "Timeout enforced on the connection to the S2A service for handshake.")
|
||||
|
||||
type s2av2TransportCreds struct {
|
||||
info *credentials.ProtocolInfo
|
||||
isClient bool
|
||||
serverName string
|
||||
s2av2Address string
|
||||
tokenManager *tokenmanager.AccessTokenManager
|
||||
// localIdentity should only be used by the client.
|
||||
localIdentity *commonpbv1.Identity
|
||||
// localIdentities should only be used by the server.
|
||||
localIdentities []*commonpbv1.Identity
|
||||
verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode
|
||||
fallbackClientHandshake fallback.ClientHandshake
|
||||
}
|
||||
|
||||
// NewClientCreds returns a client-side transport credentials object that uses
|
||||
// the S2Av2 to establish a secure connection with a server.
|
||||
func NewClientCreds(s2av2Address string, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, fallbackClientHandshakeFunc fallback.ClientHandshake) (credentials.TransportCredentials, error) {
|
||||
// Create an AccessTokenManager instance to use to authenticate to S2Av2.
|
||||
accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
|
||||
creds := &s2av2TransportCreds{
|
||||
info: &credentials.ProtocolInfo{
|
||||
SecurityProtocol: s2aSecurityProtocol,
|
||||
},
|
||||
isClient: true,
|
||||
serverName: "",
|
||||
s2av2Address: s2av2Address,
|
||||
localIdentity: localIdentity,
|
||||
verificationMode: verificationMode,
|
||||
fallbackClientHandshake: fallbackClientHandshakeFunc,
|
||||
}
|
||||
if err != nil {
|
||||
creds.tokenManager = nil
|
||||
} else {
|
||||
creds.tokenManager = &accessTokenManager
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Info("Created client S2Av2 transport credentials.")
|
||||
}
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// NewServerCreds returns a server-side transport credentials object that uses
|
||||
// the S2Av2 to establish a secure connection with a client.
|
||||
func NewServerCreds(s2av2Address string, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (credentials.TransportCredentials, error) {
|
||||
// Create an AccessTokenManager instance to use to authenticate to S2Av2.
|
||||
accessTokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
creds := &s2av2TransportCreds{
|
||||
info: &credentials.ProtocolInfo{
|
||||
SecurityProtocol: s2aSecurityProtocol,
|
||||
},
|
||||
isClient: false,
|
||||
s2av2Address: s2av2Address,
|
||||
localIdentities: localIdentities,
|
||||
verificationMode: verificationMode,
|
||||
}
|
||||
if err != nil {
|
||||
creds.tokenManager = nil
|
||||
} else {
|
||||
creds.tokenManager = &accessTokenManager
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Info("Created server S2Av2 transport credentials.")
|
||||
}
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// ClientHandshake performs a client-side mTLS handshake using the S2Av2.
|
||||
func (c *s2av2TransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||
if !c.isClient {
|
||||
return nil, nil, errors.New("client handshake called using server transport credentials")
|
||||
}
|
||||
// Remove the port from serverAuthority.
|
||||
serverName := removeServerNamePort(serverAuthority)
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, *S2ATimeout)
|
||||
defer cancel()
|
||||
cstream, err := createStream(timeoutCtx, c.s2av2Address)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to connect to S2Av2: %v", err)
|
||||
if c.fallbackClientHandshake != nil {
|
||||
return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
defer cstream.CloseSend()
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Connected to S2Av2.")
|
||||
}
|
||||
var config *tls.Config
|
||||
|
||||
var tokenManager tokenmanager.AccessTokenManager
|
||||
if c.tokenManager == nil {
|
||||
tokenManager = nil
|
||||
} else {
|
||||
tokenManager = *c.tokenManager
|
||||
}
|
||||
|
||||
if c.serverName == "" {
|
||||
config, err = tlsconfigstore.GetTLSConfigurationForClient(serverName, cstream, tokenManager, c.localIdentity, c.verificationMode)
|
||||
if err != nil {
|
||||
grpclog.Info("Failed to get client TLS config from S2Av2: %v", err)
|
||||
if c.fallbackClientHandshake != nil {
|
||||
return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
config, err = tlsconfigstore.GetTLSConfigurationForClient(c.serverName, cstream, tokenManager, c.localIdentity, c.verificationMode)
|
||||
if err != nil {
|
||||
grpclog.Info("Failed to get client TLS config from S2Av2: %v", err)
|
||||
if c.fallbackClientHandshake != nil {
|
||||
return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Got client TLS config from S2Av2.")
|
||||
}
|
||||
creds := credentials.NewTLS(config)
|
||||
|
||||
conn, authInfo, err := creds.ClientHandshake(ctx, serverName, rawConn)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to do client handshake using S2Av2: %v", err)
|
||||
if c.fallbackClientHandshake != nil {
|
||||
return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
grpclog.Infof("Successfully done client handshake using S2Av2 to: %s", serverName)
|
||||
|
||||
return conn, authInfo, err
|
||||
}
|
||||
|
||||
// ServerHandshake performs a server-side mTLS handshake using the S2Av2.
|
||||
func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||
if c.isClient {
|
||||
return nil, nil, errors.New("server handshake called using client transport credentials")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *S2ATimeout)
|
||||
defer cancel()
|
||||
cstream, err := createStream(ctx, c.s2av2Address)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to connect to S2Av2: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
defer cstream.CloseSend()
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Connected to S2Av2.")
|
||||
}
|
||||
|
||||
var tokenManager tokenmanager.AccessTokenManager
|
||||
if c.tokenManager == nil {
|
||||
tokenManager = nil
|
||||
} else {
|
||||
tokenManager = *c.tokenManager
|
||||
}
|
||||
|
||||
config, err := tlsconfigstore.GetTLSConfigurationForServer(cstream, tokenManager, c.localIdentities, c.verificationMode)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to get server TLS config from S2Av2: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Got server TLS config from S2Av2.")
|
||||
}
|
||||
creds := credentials.NewTLS(config)
|
||||
return creds.ServerHandshake(rawConn)
|
||||
}
|
||||
|
||||
// Info returns protocol info of s2av2TransportCreds.
|
||||
func (c *s2av2TransportCreds) Info() credentials.ProtocolInfo {
|
||||
return *c.info
|
||||
}
|
||||
|
||||
// Clone makes a deep copy of s2av2TransportCreds.
|
||||
func (c *s2av2TransportCreds) Clone() credentials.TransportCredentials {
|
||||
info := *c.info
|
||||
serverName := c.serverName
|
||||
fallbackClientHandshake := c.fallbackClientHandshake
|
||||
|
||||
s2av2Address := c.s2av2Address
|
||||
var tokenManager tokenmanager.AccessTokenManager
|
||||
if c.tokenManager == nil {
|
||||
tokenManager = nil
|
||||
} else {
|
||||
tokenManager = *c.tokenManager
|
||||
}
|
||||
verificationMode := c.verificationMode
|
||||
var localIdentity *commonpbv1.Identity
|
||||
if c.localIdentity != nil {
|
||||
localIdentity = proto.Clone(c.localIdentity).(*commonpbv1.Identity)
|
||||
}
|
||||
var localIdentities []*commonpbv1.Identity
|
||||
if c.localIdentities != nil {
|
||||
localIdentities = make([]*commonpbv1.Identity, len(c.localIdentities))
|
||||
for i, localIdentity := range c.localIdentities {
|
||||
localIdentities[i] = proto.Clone(localIdentity).(*commonpbv1.Identity)
|
||||
}
|
||||
}
|
||||
creds := &s2av2TransportCreds{
|
||||
info: &info,
|
||||
isClient: c.isClient,
|
||||
serverName: serverName,
|
||||
fallbackClientHandshake: fallbackClientHandshake,
|
||||
s2av2Address: s2av2Address,
|
||||
localIdentity: localIdentity,
|
||||
localIdentities: localIdentities,
|
||||
verificationMode: verificationMode,
|
||||
}
|
||||
if c.tokenManager == nil {
|
||||
creds.tokenManager = nil
|
||||
} else {
|
||||
creds.tokenManager = &tokenManager
|
||||
}
|
||||
return creds
|
||||
}
|
||||
|
||||
// NewClientTLSConfig returns a tls.Config instance that uses S2Av2 to establish a TLS connection as
|
||||
// a client. The tls.Config MUST only be used to establish a single TLS connection.
|
||||
func NewClientTLSConfig(
|
||||
ctx context.Context,
|
||||
s2av2Address string,
|
||||
tokenManager tokenmanager.AccessTokenManager,
|
||||
verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode,
|
||||
serverName string) (*tls.Config, error) {
|
||||
cstream, err := createStream(ctx, s2av2Address)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to connect to S2Av2: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tlsconfigstore.GetTLSConfigurationForClient(removeServerNamePort(serverName), cstream, tokenManager, nil, verificationMode)
|
||||
}
|
||||
|
||||
// OverrideServerName sets the ServerName in the s2av2TransportCreds protocol
|
||||
// info. The ServerName MUST be a hostname.
|
||||
func (c *s2av2TransportCreds) OverrideServerName(serverNameOverride string) error {
|
||||
serverName := removeServerNamePort(serverNameOverride)
|
||||
c.info.ServerName = serverName
|
||||
c.serverName = serverName
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove the trailing port from server name.
|
||||
func removeServerNamePort(serverName string) string {
|
||||
name, _, err := net.SplitHostPort(serverName)
|
||||
if err != nil {
|
||||
name = serverName
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func createStream(ctx context.Context, s2av2Address string) (s2av2pb.S2AService_SetUpSessionClient, error) {
|
||||
// TODO(rmehta19): Consider whether to close the connection to S2Av2.
|
||||
conn, err := service.Dial(s2av2Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client := s2av2pb.NewS2AServiceClient(conn)
|
||||
return client.SetUpSession(ctx, []grpc.CallOption{}...)
|
||||
}
|
||||
24
vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/testdata/client_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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/testdata/client_key.pem
generated
vendored
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/testdata/client_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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/testdata/server_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/testdata/server_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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/testdata/server_key.pem
generated
vendored
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/testdata/server_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/client_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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
Normal file
24
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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
Normal file
27
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/testdata/server_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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-----
|
||||
403
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go
generated
vendored
Normal file
403
vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go
generated
vendored
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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 tlsconfigstore offloads operations to S2Av2.
|
||||
package tlsconfigstore
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
"github.com/google/s2a-go/internal/v2/certverifier"
|
||||
"github.com/google/s2a-go/internal/v2/remotesigner"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
commonpbv1 "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
commonpb "github.com/google/s2a-go/internal/proto/v2/common_go_proto"
|
||||
s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
|
||||
)
|
||||
|
||||
const (
|
||||
// HTTP/2
|
||||
h2 = "h2"
|
||||
)
|
||||
|
||||
// GetTLSConfigurationForClient returns a tls.Config instance for use by a client application.
|
||||
func GetTLSConfigurationForClient(serverHostname string, cstream s2av2pb.S2AService_SetUpSessionClient, tokenManager tokenmanager.AccessTokenManager, localIdentity *commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (*tls.Config, error) {
|
||||
authMechanisms := getAuthMechanisms(tokenManager, []*commonpbv1.Identity{localIdentity})
|
||||
|
||||
if grpclog.V(1) {
|
||||
grpclog.Infof("Sending request to S2Av2 for client TLS config.")
|
||||
}
|
||||
// Send request to S2Av2 for config.
|
||||
if err := cstream.Send(&s2av2pb.SessionReq{
|
||||
LocalIdentity: localIdentity,
|
||||
AuthenticationMechanisms: authMechanisms,
|
||||
ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{
|
||||
GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{
|
||||
ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_CLIENT,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
grpclog.Infof("Failed to send request to S2Av2 for client TLS config")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the response containing config from S2Av2.
|
||||
resp, err := cstream.Recv()
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to receive client TLS config response from S2Av2.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(rmehta19): Add unit test for this if statement.
|
||||
if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
|
||||
return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
|
||||
}
|
||||
|
||||
// Extract TLS configiguration from SessionResp.
|
||||
tlsConfig := resp.GetGetTlsConfigurationResp().GetClientTlsConfiguration()
|
||||
|
||||
var cert tls.Certificate
|
||||
for i, v := range tlsConfig.CertificateChain {
|
||||
// Populate Certificates field.
|
||||
block, _ := pem.Decode([]byte(v))
|
||||
if block == nil {
|
||||
return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty")
|
||||
}
|
||||
x509Cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert.Certificate = append(cert.Certificate, x509Cert.Raw)
|
||||
if i == 0 {
|
||||
cert.Leaf = x509Cert
|
||||
}
|
||||
}
|
||||
|
||||
if len(tlsConfig.CertificateChain) > 0 {
|
||||
cert.PrivateKey = remotesigner.New(cert.Leaf, cstream)
|
||||
if cert.PrivateKey == nil {
|
||||
return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
|
||||
}
|
||||
}
|
||||
|
||||
minVersion, maxVersion, err := getTLSMinMaxVersionsClient(tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create mTLS credentials for client.
|
||||
config := &tls.Config{
|
||||
VerifyPeerCertificate: certverifier.VerifyServerCertificateChain(serverHostname, verificationMode, cstream),
|
||||
ServerName: serverHostname,
|
||||
InsecureSkipVerify: true, // NOLINT
|
||||
ClientSessionCache: nil,
|
||||
SessionTicketsDisabled: true,
|
||||
MinVersion: minVersion,
|
||||
MaxVersion: maxVersion,
|
||||
NextProtos: []string{h2},
|
||||
}
|
||||
if len(tlsConfig.CertificateChain) > 0 {
|
||||
config.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// GetTLSConfigurationForServer returns a tls.Config instance for use by a server application.
|
||||
func GetTLSConfigurationForServer(cstream s2av2pb.S2AService_SetUpSessionClient, tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode) (*tls.Config, error) {
|
||||
return &tls.Config{
|
||||
GetConfigForClient: ClientConfig(tokenManager, localIdentities, verificationMode, cstream),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ClientConfig builds a TLS config for a server to establish a secure
|
||||
// connection with a client, based on SNI communicated during ClientHello.
|
||||
// Ensures that server presents the correct certificate to establish a TLS
|
||||
// connection.
|
||||
func ClientConfig(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode, cstream s2av2pb.S2AService_SetUpSessionClient) func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
tlsConfig, err := getServerConfigFromS2Av2(tokenManager, localIdentities, chi.ServerName, cstream)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cert tls.Certificate
|
||||
for i, v := range tlsConfig.CertificateChain {
|
||||
// Populate Certificates field.
|
||||
block, _ := pem.Decode([]byte(v))
|
||||
if block == nil {
|
||||
return nil, errors.New("certificate in CertificateChain obtained from S2Av2 is empty")
|
||||
}
|
||||
x509Cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert.Certificate = append(cert.Certificate, x509Cert.Raw)
|
||||
if i == 0 {
|
||||
cert.Leaf = x509Cert
|
||||
}
|
||||
}
|
||||
|
||||
cert.PrivateKey = remotesigner.New(cert.Leaf, cstream)
|
||||
if cert.PrivateKey == nil {
|
||||
return nil, errors.New("failed to retrieve Private Key from Remote Signer Library")
|
||||
}
|
||||
|
||||
minVersion, maxVersion, err := getTLSMinMaxVersionsServer(tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clientAuth := getTLSClientAuthType(tlsConfig)
|
||||
|
||||
var cipherSuites []uint16
|
||||
cipherSuites = getCipherSuites(tlsConfig.Ciphersuites)
|
||||
|
||||
// Create mTLS credentials for server.
|
||||
return &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
VerifyPeerCertificate: certverifier.VerifyClientCertificateChain(verificationMode, cstream),
|
||||
ClientAuth: clientAuth,
|
||||
CipherSuites: cipherSuites,
|
||||
SessionTicketsDisabled: true,
|
||||
MinVersion: minVersion,
|
||||
MaxVersion: maxVersion,
|
||||
NextProtos: []string{h2},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getCipherSuites(tlsConfigCipherSuites []commonpb.Ciphersuite) []uint16 {
|
||||
var tlsGoCipherSuites []uint16
|
||||
for _, v := range tlsConfigCipherSuites {
|
||||
s := getTLSCipherSuite(v)
|
||||
if s != 0xffff {
|
||||
tlsGoCipherSuites = append(tlsGoCipherSuites, s)
|
||||
}
|
||||
}
|
||||
return tlsGoCipherSuites
|
||||
}
|
||||
|
||||
func getTLSCipherSuite(tlsCipherSuite commonpb.Ciphersuite) uint16 {
|
||||
switch tlsCipherSuite {
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
||||
return tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
|
||||
return tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
case commonpb.Ciphersuite_CIPHERSUITE_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
|
||||
return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
default:
|
||||
return 0xffff
|
||||
}
|
||||
}
|
||||
|
||||
func getServerConfigFromS2Av2(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity, sni string, cstream s2av2pb.S2AService_SetUpSessionClient) (*s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration, error) {
|
||||
authMechanisms := getAuthMechanisms(tokenManager, localIdentities)
|
||||
var locID *commonpbv1.Identity
|
||||
if localIdentities != nil {
|
||||
locID = localIdentities[0]
|
||||
}
|
||||
|
||||
if err := cstream.Send(&s2av2pb.SessionReq{
|
||||
LocalIdentity: locID,
|
||||
AuthenticationMechanisms: authMechanisms,
|
||||
ReqOneof: &s2av2pb.SessionReq_GetTlsConfigurationReq{
|
||||
GetTlsConfigurationReq: &s2av2pb.GetTlsConfigurationReq{
|
||||
ConnectionSide: commonpb.ConnectionSide_CONNECTION_SIDE_SERVER,
|
||||
Sni: sni,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := cstream.Recv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(rmehta19): Add unit test for this if statement.
|
||||
if (resp.GetStatus() != nil) && (resp.GetStatus().Code != uint32(codes.OK)) {
|
||||
return nil, fmt.Errorf("failed to get TLS configuration from S2A: %d, %v", resp.GetStatus().Code, resp.GetStatus().Details)
|
||||
}
|
||||
|
||||
return resp.GetGetTlsConfigurationResp().GetServerTlsConfiguration(), nil
|
||||
}
|
||||
|
||||
func getTLSClientAuthType(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) tls.ClientAuthType {
|
||||
var clientAuth tls.ClientAuthType
|
||||
switch x := tlsConfig.RequestClientCertificate; x {
|
||||
case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_DONT_REQUEST_CLIENT_CERTIFICATE:
|
||||
clientAuth = tls.NoClientCert
|
||||
case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
|
||||
clientAuth = tls.RequestClientCert
|
||||
case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
|
||||
// This case actually maps to tls.VerifyClientCertIfGiven. However this
|
||||
// mapping triggers normal verification, followed by custom verification,
|
||||
// specified in VerifyPeerCertificate. To bypass normal verification, and
|
||||
// only do custom verification we set clientAuth to RequireAnyClientCert or
|
||||
// RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
|
||||
// discussion.
|
||||
clientAuth = tls.RequireAnyClientCert
|
||||
case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
|
||||
clientAuth = tls.RequireAnyClientCert
|
||||
case s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
|
||||
// This case actually maps to tls.RequireAndVerifyClientCert. However this
|
||||
// mapping triggers normal verification, followed by custom verification,
|
||||
// specified in VerifyPeerCertificate. To bypass normal verification, and
|
||||
// only do custom verification we set clientAuth to RequireAnyClientCert or
|
||||
// RequestClientCert. See https://github.com/google/s2a-go/pull/43 for full
|
||||
// discussion.
|
||||
clientAuth = tls.RequireAnyClientCert
|
||||
default:
|
||||
clientAuth = tls.RequireAnyClientCert
|
||||
}
|
||||
return clientAuth
|
||||
}
|
||||
|
||||
func getAuthMechanisms(tokenManager tokenmanager.AccessTokenManager, localIdentities []*commonpbv1.Identity) []*s2av2pb.AuthenticationMechanism {
|
||||
if tokenManager == nil {
|
||||
return nil
|
||||
}
|
||||
if len(localIdentities) == 0 {
|
||||
token, err := tokenManager.DefaultToken()
|
||||
if err != nil {
|
||||
grpclog.Infof("Unable to get token for empty local identity: %v", err)
|
||||
return nil
|
||||
}
|
||||
return []*s2av2pb.AuthenticationMechanism{
|
||||
{
|
||||
MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
var authMechanisms []*s2av2pb.AuthenticationMechanism
|
||||
for _, localIdentity := range localIdentities {
|
||||
if localIdentity == nil {
|
||||
token, err := tokenManager.DefaultToken()
|
||||
if err != nil {
|
||||
grpclog.Infof("Unable to get default token for local identity %v: %v", localIdentity, err)
|
||||
continue
|
||||
}
|
||||
authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
|
||||
Identity: localIdentity,
|
||||
MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
token, err := tokenManager.Token(localIdentity)
|
||||
if err != nil {
|
||||
grpclog.Infof("Unable to get token for local identity %v: %v", localIdentity, err)
|
||||
continue
|
||||
}
|
||||
authMechanisms = append(authMechanisms, &s2av2pb.AuthenticationMechanism{
|
||||
Identity: localIdentity,
|
||||
MechanismOneof: &s2av2pb.AuthenticationMechanism_Token{
|
||||
Token: token,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
return authMechanisms
|
||||
}
|
||||
|
||||
// TODO(rmehta19): refactor switch statements into a helper function.
|
||||
func getTLSMinMaxVersionsClient(tlsConfig *s2av2pb.GetTlsConfigurationResp_ClientTlsConfiguration) (uint16, uint16, error) {
|
||||
// Map S2Av2 TLSVersion to consts defined in tls package.
|
||||
var minVersion uint16
|
||||
var maxVersion uint16
|
||||
switch x := tlsConfig.MinTlsVersion; x {
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_0:
|
||||
minVersion = tls.VersionTLS10
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_1:
|
||||
minVersion = tls.VersionTLS11
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_2:
|
||||
minVersion = tls.VersionTLS12
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_3:
|
||||
minVersion = tls.VersionTLS13
|
||||
default:
|
||||
return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
|
||||
}
|
||||
|
||||
switch x := tlsConfig.MaxTlsVersion; x {
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_0:
|
||||
maxVersion = tls.VersionTLS10
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_1:
|
||||
maxVersion = tls.VersionTLS11
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_2:
|
||||
maxVersion = tls.VersionTLS12
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_3:
|
||||
maxVersion = tls.VersionTLS13
|
||||
default:
|
||||
return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
|
||||
}
|
||||
if minVersion > maxVersion {
|
||||
return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
|
||||
}
|
||||
return minVersion, maxVersion, nil
|
||||
}
|
||||
|
||||
func getTLSMinMaxVersionsServer(tlsConfig *s2av2pb.GetTlsConfigurationResp_ServerTlsConfiguration) (uint16, uint16, error) {
|
||||
// Map S2Av2 TLSVersion to consts defined in tls package.
|
||||
var minVersion uint16
|
||||
var maxVersion uint16
|
||||
switch x := tlsConfig.MinTlsVersion; x {
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_0:
|
||||
minVersion = tls.VersionTLS10
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_1:
|
||||
minVersion = tls.VersionTLS11
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_2:
|
||||
minVersion = tls.VersionTLS12
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_3:
|
||||
minVersion = tls.VersionTLS13
|
||||
default:
|
||||
return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MinTlsVersion: %v", x)
|
||||
}
|
||||
|
||||
switch x := tlsConfig.MaxTlsVersion; x {
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_0:
|
||||
maxVersion = tls.VersionTLS10
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_1:
|
||||
maxVersion = tls.VersionTLS11
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_2:
|
||||
maxVersion = tls.VersionTLS12
|
||||
case commonpb.TLSVersion_TLS_VERSION_1_3:
|
||||
maxVersion = tls.VersionTLS13
|
||||
default:
|
||||
return minVersion, maxVersion, fmt.Errorf("S2Av2 provided invalid MaxTlsVersion: %v", x)
|
||||
}
|
||||
if minVersion > maxVersion {
|
||||
return minVersion, maxVersion, errors.New("S2Av2 provided minVersion > maxVersion")
|
||||
}
|
||||
return minVersion, maxVersion, nil
|
||||
}
|
||||
409
vendor/github.com/google/s2a-go/s2a.go
generated
vendored
Normal file
409
vendor/github.com/google/s2a-go/s2a.go
generated
vendored
Normal file
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 s2a provides the S2A transport credentials used by a gRPC
|
||||
// application.
|
||||
package s2a
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/google/s2a-go/fallback"
|
||||
"github.com/google/s2a-go/internal/handshaker"
|
||||
"github.com/google/s2a-go/internal/handshaker/service"
|
||||
"github.com/google/s2a-go/internal/tokenmanager"
|
||||
"github.com/google/s2a-go/internal/v2"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
s2av2pb "github.com/google/s2a-go/internal/proto/v2/s2a_go_proto"
|
||||
)
|
||||
|
||||
const (
|
||||
s2aSecurityProtocol = "tls"
|
||||
// defaultTimeout specifies the default server handshake timeout.
|
||||
defaultTimeout = 30.0 * time.Second
|
||||
)
|
||||
|
||||
// s2aTransportCreds are the transport credentials required for establishing
|
||||
// a secure connection using the S2A. They implement the
|
||||
// credentials.TransportCredentials interface.
|
||||
type s2aTransportCreds struct {
|
||||
info *credentials.ProtocolInfo
|
||||
minTLSVersion commonpb.TLSVersion
|
||||
maxTLSVersion commonpb.TLSVersion
|
||||
// tlsCiphersuites contains the ciphersuites used in the S2A connection.
|
||||
// Note that these are currently unconfigurable.
|
||||
tlsCiphersuites []commonpb.Ciphersuite
|
||||
// localIdentity should only be used by the client.
|
||||
localIdentity *commonpb.Identity
|
||||
// localIdentities should only be used by the server.
|
||||
localIdentities []*commonpb.Identity
|
||||
// targetIdentities should only be used by the client.
|
||||
targetIdentities []*commonpb.Identity
|
||||
isClient bool
|
||||
s2aAddr string
|
||||
ensureProcessSessionTickets *sync.WaitGroup
|
||||
}
|
||||
|
||||
// NewClientCreds returns a client-side transport credentials object that uses
|
||||
// the S2A to establish a secure connection with a server.
|
||||
func NewClientCreds(opts *ClientOptions) (credentials.TransportCredentials, error) {
|
||||
if opts == nil {
|
||||
return nil, errors.New("nil client options")
|
||||
}
|
||||
var targetIdentities []*commonpb.Identity
|
||||
for _, targetIdentity := range opts.TargetIdentities {
|
||||
protoTargetIdentity, err := toProtoIdentity(targetIdentity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
targetIdentities = append(targetIdentities, protoTargetIdentity)
|
||||
}
|
||||
localIdentity, err := toProtoIdentity(opts.LocalIdentity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if opts.EnableLegacyMode {
|
||||
return &s2aTransportCreds{
|
||||
info: &credentials.ProtocolInfo{
|
||||
SecurityProtocol: s2aSecurityProtocol,
|
||||
},
|
||||
minTLSVersion: commonpb.TLSVersion_TLS1_3,
|
||||
maxTLSVersion: commonpb.TLSVersion_TLS1_3,
|
||||
tlsCiphersuites: []commonpb.Ciphersuite{
|
||||
commonpb.Ciphersuite_AES_128_GCM_SHA256,
|
||||
commonpb.Ciphersuite_AES_256_GCM_SHA384,
|
||||
commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
|
||||
},
|
||||
localIdentity: localIdentity,
|
||||
targetIdentities: targetIdentities,
|
||||
isClient: true,
|
||||
s2aAddr: opts.S2AAddress,
|
||||
ensureProcessSessionTickets: opts.EnsureProcessSessionTickets,
|
||||
}, nil
|
||||
}
|
||||
verificationMode := getVerificationMode(opts.VerificationMode)
|
||||
var fallbackFunc fallback.ClientHandshake
|
||||
if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackClientHandshakeFunc != nil {
|
||||
fallbackFunc = opts.FallbackOpts.FallbackClientHandshakeFunc
|
||||
}
|
||||
return v2.NewClientCreds(opts.S2AAddress, localIdentity, verificationMode, fallbackFunc)
|
||||
}
|
||||
|
||||
// NewServerCreds returns a server-side transport credentials object that uses
|
||||
// the S2A to establish a secure connection with a client.
|
||||
func NewServerCreds(opts *ServerOptions) (credentials.TransportCredentials, error) {
|
||||
if opts == nil {
|
||||
return nil, errors.New("nil server options")
|
||||
}
|
||||
var localIdentities []*commonpb.Identity
|
||||
for _, localIdentity := range opts.LocalIdentities {
|
||||
protoLocalIdentity, err := toProtoIdentity(localIdentity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
localIdentities = append(localIdentities, protoLocalIdentity)
|
||||
}
|
||||
if opts.EnableLegacyMode {
|
||||
return &s2aTransportCreds{
|
||||
info: &credentials.ProtocolInfo{
|
||||
SecurityProtocol: s2aSecurityProtocol,
|
||||
},
|
||||
minTLSVersion: commonpb.TLSVersion_TLS1_3,
|
||||
maxTLSVersion: commonpb.TLSVersion_TLS1_3,
|
||||
tlsCiphersuites: []commonpb.Ciphersuite{
|
||||
commonpb.Ciphersuite_AES_128_GCM_SHA256,
|
||||
commonpb.Ciphersuite_AES_256_GCM_SHA384,
|
||||
commonpb.Ciphersuite_CHACHA20_POLY1305_SHA256,
|
||||
},
|
||||
localIdentities: localIdentities,
|
||||
isClient: false,
|
||||
s2aAddr: opts.S2AAddress,
|
||||
}, nil
|
||||
}
|
||||
verificationMode := getVerificationMode(opts.VerificationMode)
|
||||
return v2.NewServerCreds(opts.S2AAddress, localIdentities, verificationMode)
|
||||
}
|
||||
|
||||
// ClientHandshake initiates a client-side TLS handshake using the S2A.
|
||||
func (c *s2aTransportCreds) ClientHandshake(ctx context.Context, serverAuthority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||
if !c.isClient {
|
||||
return nil, nil, errors.New("client handshake called using server transport credentials")
|
||||
}
|
||||
|
||||
// Connect to the S2A.
|
||||
hsConn, err := service.Dial(c.s2aAddr)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to connect to S2A: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
opts := &handshaker.ClientHandshakerOptions{
|
||||
MinTLSVersion: c.minTLSVersion,
|
||||
MaxTLSVersion: c.maxTLSVersion,
|
||||
TLSCiphersuites: c.tlsCiphersuites,
|
||||
TargetIdentities: c.targetIdentities,
|
||||
LocalIdentity: c.localIdentity,
|
||||
TargetName: serverAuthority,
|
||||
EnsureProcessSessionTickets: c.ensureProcessSessionTickets,
|
||||
}
|
||||
chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
|
||||
if err != nil {
|
||||
grpclog.Infof("Call to handshaker.NewClientHandshaker failed: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if closeErr := chs.Close(); closeErr != nil {
|
||||
grpclog.Infof("Close failed unexpectedly: %v", err)
|
||||
err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
secConn, authInfo, err := chs.ClientHandshake(context.Background())
|
||||
if err != nil {
|
||||
grpclog.Infof("Handshake failed: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
return secConn, authInfo, nil
|
||||
}
|
||||
|
||||
// ServerHandshake initiates a server-side TLS handshake using the S2A.
|
||||
func (c *s2aTransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||
if c.isClient {
|
||||
return nil, nil, errors.New("server handshake called using client transport credentials")
|
||||
}
|
||||
|
||||
// Connect to the S2A.
|
||||
hsConn, err := service.Dial(c.s2aAddr)
|
||||
if err != nil {
|
||||
grpclog.Infof("Failed to connect to S2A: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
opts := &handshaker.ServerHandshakerOptions{
|
||||
MinTLSVersion: c.minTLSVersion,
|
||||
MaxTLSVersion: c.maxTLSVersion,
|
||||
TLSCiphersuites: c.tlsCiphersuites,
|
||||
LocalIdentities: c.localIdentities,
|
||||
}
|
||||
shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, c.s2aAddr, opts)
|
||||
if err != nil {
|
||||
grpclog.Infof("Call to handshaker.NewServerHandshaker failed: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if closeErr := shs.Close(); closeErr != nil {
|
||||
grpclog.Infof("Close failed unexpectedly: %v", err)
|
||||
err = fmt.Errorf("%v: close unexpectedly failed: %v", err, closeErr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
secConn, authInfo, err := shs.ServerHandshake(context.Background())
|
||||
if err != nil {
|
||||
grpclog.Infof("Handshake failed: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
return secConn, authInfo, nil
|
||||
}
|
||||
|
||||
func (c *s2aTransportCreds) Info() credentials.ProtocolInfo {
|
||||
return *c.info
|
||||
}
|
||||
|
||||
func (c *s2aTransportCreds) Clone() credentials.TransportCredentials {
|
||||
info := *c.info
|
||||
var localIdentity *commonpb.Identity
|
||||
if c.localIdentity != nil {
|
||||
localIdentity = proto.Clone(c.localIdentity).(*commonpb.Identity)
|
||||
}
|
||||
var localIdentities []*commonpb.Identity
|
||||
if c.localIdentities != nil {
|
||||
localIdentities = make([]*commonpb.Identity, len(c.localIdentities))
|
||||
for i, localIdentity := range c.localIdentities {
|
||||
localIdentities[i] = proto.Clone(localIdentity).(*commonpb.Identity)
|
||||
}
|
||||
}
|
||||
var targetIdentities []*commonpb.Identity
|
||||
if c.targetIdentities != nil {
|
||||
targetIdentities = make([]*commonpb.Identity, len(c.targetIdentities))
|
||||
for i, targetIdentity := range c.targetIdentities {
|
||||
targetIdentities[i] = proto.Clone(targetIdentity).(*commonpb.Identity)
|
||||
}
|
||||
}
|
||||
return &s2aTransportCreds{
|
||||
info: &info,
|
||||
minTLSVersion: c.minTLSVersion,
|
||||
maxTLSVersion: c.maxTLSVersion,
|
||||
tlsCiphersuites: c.tlsCiphersuites,
|
||||
localIdentity: localIdentity,
|
||||
localIdentities: localIdentities,
|
||||
targetIdentities: targetIdentities,
|
||||
isClient: c.isClient,
|
||||
s2aAddr: c.s2aAddr,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *s2aTransportCreds) OverrideServerName(serverNameOverride string) error {
|
||||
c.info.ServerName = serverNameOverride
|
||||
return nil
|
||||
}
|
||||
|
||||
// TLSClientConfigOptions specifies parameters for creating client TLS config.
|
||||
type TLSClientConfigOptions struct {
|
||||
// ServerName is required by s2a as the expected name when verifying the hostname found in server's certificate.
|
||||
// tlsConfig, _ := factory.Build(ctx, &s2a.TLSClientConfigOptions{
|
||||
// ServerName: "example.com",
|
||||
// })
|
||||
ServerName string
|
||||
}
|
||||
|
||||
// TLSClientConfigFactory defines the interface for a client TLS config factory.
|
||||
type TLSClientConfigFactory interface {
|
||||
Build(ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error)
|
||||
}
|
||||
|
||||
// NewTLSClientConfigFactory returns an instance of s2aTLSClientConfigFactory.
|
||||
func NewTLSClientConfigFactory(opts *ClientOptions) (TLSClientConfigFactory, error) {
|
||||
if opts == nil {
|
||||
return nil, fmt.Errorf("opts must be non-nil")
|
||||
}
|
||||
if opts.EnableLegacyMode {
|
||||
return nil, fmt.Errorf("NewTLSClientConfigFactory only supports S2Av2")
|
||||
}
|
||||
tokenManager, err := tokenmanager.NewSingleTokenAccessTokenManager()
|
||||
if err != nil {
|
||||
// The only possible error is: access token not set in the environment,
|
||||
// which is okay in environments other than serverless.
|
||||
grpclog.Infof("Access token manager not initialized: %v", err)
|
||||
return &s2aTLSClientConfigFactory{
|
||||
s2av2Address: opts.S2AAddress,
|
||||
tokenManager: nil,
|
||||
verificationMode: getVerificationMode(opts.VerificationMode),
|
||||
}, nil
|
||||
}
|
||||
return &s2aTLSClientConfigFactory{
|
||||
s2av2Address: opts.S2AAddress,
|
||||
tokenManager: tokenManager,
|
||||
verificationMode: getVerificationMode(opts.VerificationMode),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type s2aTLSClientConfigFactory struct {
|
||||
s2av2Address string
|
||||
tokenManager tokenmanager.AccessTokenManager
|
||||
verificationMode s2av2pb.ValidatePeerCertificateChainReq_VerificationMode
|
||||
}
|
||||
|
||||
func (f *s2aTLSClientConfigFactory) Build(
|
||||
ctx context.Context, opts *TLSClientConfigOptions) (*tls.Config, error) {
|
||||
serverName := ""
|
||||
if opts != nil && opts.ServerName != "" {
|
||||
serverName = opts.ServerName
|
||||
}
|
||||
return v2.NewClientTLSConfig(ctx, f.s2av2Address, f.tokenManager, f.verificationMode, serverName)
|
||||
}
|
||||
|
||||
func getVerificationMode(verificationMode VerificationModeType) s2av2pb.ValidatePeerCertificateChainReq_VerificationMode {
|
||||
switch verificationMode {
|
||||
case ConnectToGoogle:
|
||||
return s2av2pb.ValidatePeerCertificateChainReq_CONNECT_TO_GOOGLE
|
||||
case Spiffe:
|
||||
return s2av2pb.ValidatePeerCertificateChainReq_SPIFFE
|
||||
default:
|
||||
return s2av2pb.ValidatePeerCertificateChainReq_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
// NewS2ADialTLSContextFunc returns a dialer which establishes an MTLS connection using S2A.
|
||||
// Example use with http.RoundTripper:
|
||||
//
|
||||
// dialTLSContext := s2a.NewS2aDialTLSContextFunc(&s2a.ClientOptions{
|
||||
// S2AAddress: s2aAddress, // required
|
||||
// })
|
||||
// transport := http.DefaultTransport
|
||||
// transport.DialTLSContext = dialTLSContext
|
||||
func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
|
||||
return func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
|
||||
fallback := func(err error) (net.Conn, error) {
|
||||
if opts.FallbackOpts != nil && opts.FallbackOpts.FallbackDialer != nil &&
|
||||
opts.FallbackOpts.FallbackDialer.Dialer != nil && opts.FallbackOpts.FallbackDialer.ServerAddr != "" {
|
||||
fbDialer := opts.FallbackOpts.FallbackDialer
|
||||
grpclog.Infof("fall back to dial: %s", fbDialer.ServerAddr)
|
||||
fbConn, fbErr := fbDialer.Dialer.DialContext(ctx, network, fbDialer.ServerAddr)
|
||||
if fbErr != nil {
|
||||
return nil, fmt.Errorf("error fallback to %s: %v; S2A error: %w", fbDialer.ServerAddr, fbErr, err)
|
||||
}
|
||||
return fbConn, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
factory, err := NewTLSClientConfigFactory(opts)
|
||||
if err != nil {
|
||||
grpclog.Infof("error creating S2A client config factory: %v", err)
|
||||
return fallback(err)
|
||||
}
|
||||
|
||||
serverName, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
serverName = addr
|
||||
}
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, *v2.S2ATimeout)
|
||||
defer cancel()
|
||||
s2aTLSConfig, err := factory.Build(timeoutCtx, &TLSClientConfigOptions{
|
||||
ServerName: serverName,
|
||||
})
|
||||
if err != nil {
|
||||
grpclog.Infof("error building S2A TLS config: %v", err)
|
||||
return fallback(err)
|
||||
}
|
||||
|
||||
s2aDialer := &tls.Dialer{
|
||||
Config: s2aTLSConfig,
|
||||
}
|
||||
c, err := s2aDialer.DialContext(ctx, network, addr)
|
||||
if err != nil {
|
||||
grpclog.Infof("error dialing with S2A to %s: %v", addr, err)
|
||||
return fallback(err)
|
||||
}
|
||||
grpclog.Infof("success dialing MTLS to %s with S2A", addr)
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
197
vendor/github.com/google/s2a-go/s2a_options.go
generated
vendored
Normal file
197
vendor/github.com/google/s2a-go/s2a_options.go
generated
vendored
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 s2a
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/google/s2a-go/fallback"
|
||||
|
||||
s2apb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
)
|
||||
|
||||
// Identity is the interface for S2A identities.
|
||||
type Identity interface {
|
||||
// Name returns the name of the identity.
|
||||
Name() string
|
||||
}
|
||||
|
||||
type spiffeID struct {
|
||||
spiffeID string
|
||||
}
|
||||
|
||||
func (s *spiffeID) Name() string { return s.spiffeID }
|
||||
|
||||
// NewSpiffeID creates a SPIFFE ID from id.
|
||||
func NewSpiffeID(id string) Identity {
|
||||
return &spiffeID{spiffeID: id}
|
||||
}
|
||||
|
||||
type hostname struct {
|
||||
hostname string
|
||||
}
|
||||
|
||||
func (h *hostname) Name() string { return h.hostname }
|
||||
|
||||
// NewHostname creates a hostname from name.
|
||||
func NewHostname(name string) Identity {
|
||||
return &hostname{hostname: name}
|
||||
}
|
||||
|
||||
type uid struct {
|
||||
uid string
|
||||
}
|
||||
|
||||
func (h *uid) Name() string { return h.uid }
|
||||
|
||||
// NewUID creates a UID from name.
|
||||
func NewUID(name string) Identity {
|
||||
return &uid{uid: name}
|
||||
}
|
||||
|
||||
// VerificationModeType specifies the mode that S2A must use to verify the peer
|
||||
// certificate chain.
|
||||
type VerificationModeType int
|
||||
|
||||
// Three types of verification modes.
|
||||
const (
|
||||
Unspecified = iota
|
||||
ConnectToGoogle
|
||||
Spiffe
|
||||
)
|
||||
|
||||
// ClientOptions contains the client-side options used to establish a secure
|
||||
// channel using the S2A handshaker service.
|
||||
type ClientOptions struct {
|
||||
// TargetIdentities contains a list of allowed server identities. One of the
|
||||
// target identities should match the peer identity in the handshake
|
||||
// result; otherwise, the handshake fails.
|
||||
TargetIdentities []Identity
|
||||
// LocalIdentity is the local identity of the client application. If none is
|
||||
// provided, then the S2A will choose the default identity, if one exists.
|
||||
LocalIdentity Identity
|
||||
// S2AAddress is the address of the S2A.
|
||||
S2AAddress string
|
||||
// EnsureProcessSessionTickets waits for all session tickets to be sent to
|
||||
// S2A before a process completes.
|
||||
//
|
||||
// This functionality is crucial for processes that complete very soon after
|
||||
// using S2A to establish a TLS connection, but it can be ignored for longer
|
||||
// lived processes.
|
||||
//
|
||||
// Usage example:
|
||||
// func main() {
|
||||
// var ensureProcessSessionTickets sync.WaitGroup
|
||||
// clientOpts := &s2a.ClientOptions{
|
||||
// EnsureProcessSessionTickets: &ensureProcessSessionTickets,
|
||||
// // Set other members.
|
||||
// }
|
||||
// creds, _ := s2a.NewClientCreds(clientOpts)
|
||||
// conn, _ := grpc.Dial(serverAddr, grpc.WithTransportCredentials(creds))
|
||||
// defer conn.Close()
|
||||
//
|
||||
// // Make RPC call.
|
||||
//
|
||||
// // The process terminates right after the RPC call ends.
|
||||
// // ensureProcessSessionTickets can be used to ensure resumption
|
||||
// // tickets are fully processed. If the process is long-lived, using
|
||||
// // ensureProcessSessionTickets is not necessary.
|
||||
// ensureProcessSessionTickets.Wait()
|
||||
// }
|
||||
EnsureProcessSessionTickets *sync.WaitGroup
|
||||
// If true, enables the use of legacy S2Av1.
|
||||
EnableLegacyMode bool
|
||||
// VerificationMode specifies the mode that S2A must use to verify the
|
||||
// peer certificate chain.
|
||||
VerificationMode VerificationModeType
|
||||
|
||||
// Optional fallback after dialing with S2A fails.
|
||||
FallbackOpts *FallbackOptions
|
||||
}
|
||||
|
||||
// FallbackOptions prescribes the fallback logic that should be taken if the application fails to connect with S2A.
|
||||
type FallbackOptions struct {
|
||||
// FallbackClientHandshakeFunc is used to specify fallback behavior when calling s2a.NewClientCreds().
|
||||
// It will be called by ClientHandshake function, after handshake with S2A fails.
|
||||
// s2a.NewClientCreds() ignores the other FallbackDialer field.
|
||||
FallbackClientHandshakeFunc fallback.ClientHandshake
|
||||
|
||||
// FallbackDialer is used to specify fallback behavior when calling s2a.NewS2aDialTLSContextFunc().
|
||||
// It passes in a custom fallback dialer and server address to use after dialing with S2A fails.
|
||||
// s2a.NewS2aDialTLSContextFunc() ignores the other FallbackClientHandshakeFunc field.
|
||||
FallbackDialer *FallbackDialer
|
||||
}
|
||||
|
||||
// FallbackDialer contains a fallback tls.Dialer and a server address to connect to.
|
||||
type FallbackDialer struct {
|
||||
// Dialer specifies a fallback tls.Dialer.
|
||||
Dialer *tls.Dialer
|
||||
// ServerAddr is used by Dialer to establish fallback connection.
|
||||
ServerAddr string
|
||||
}
|
||||
|
||||
// DefaultClientOptions returns the default client options.
|
||||
func DefaultClientOptions(s2aAddress string) *ClientOptions {
|
||||
return &ClientOptions{
|
||||
S2AAddress: s2aAddress,
|
||||
VerificationMode: ConnectToGoogle,
|
||||
}
|
||||
}
|
||||
|
||||
// ServerOptions contains the server-side options used to establish a secure
|
||||
// channel using the S2A handshaker service.
|
||||
type ServerOptions struct {
|
||||
// LocalIdentities is the list of local identities that may be assumed by
|
||||
// the server. If no local identity is specified, then the S2A chooses a
|
||||
// default local identity, if one exists.
|
||||
LocalIdentities []Identity
|
||||
// S2AAddress is the address of the S2A.
|
||||
S2AAddress string
|
||||
// If true, enables the use of legacy S2Av1.
|
||||
EnableLegacyMode bool
|
||||
// VerificationMode specifies the mode that S2A must use to verify the
|
||||
// peer certificate chain.
|
||||
VerificationMode VerificationModeType
|
||||
}
|
||||
|
||||
// DefaultServerOptions returns the default server options.
|
||||
func DefaultServerOptions(s2aAddress string) *ServerOptions {
|
||||
return &ServerOptions{
|
||||
S2AAddress: s2aAddress,
|
||||
VerificationMode: ConnectToGoogle,
|
||||
}
|
||||
}
|
||||
|
||||
func toProtoIdentity(identity Identity) (*s2apb.Identity, error) {
|
||||
if identity == nil {
|
||||
return nil, nil
|
||||
}
|
||||
switch id := identity.(type) {
|
||||
case *spiffeID:
|
||||
return &s2apb.Identity{IdentityOneof: &s2apb.Identity_SpiffeId{SpiffeId: id.Name()}}, nil
|
||||
case *hostname:
|
||||
return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Hostname{Hostname: id.Name()}}, nil
|
||||
case *uid:
|
||||
return &s2apb.Identity{IdentityOneof: &s2apb.Identity_Uid{Uid: id.Name()}}, nil
|
||||
default:
|
||||
return nil, errors.New("unrecognized identity type")
|
||||
}
|
||||
}
|
||||
79
vendor/github.com/google/s2a-go/s2a_utils.go
generated
vendored
Normal file
79
vendor/github.com/google/s2a-go/s2a_utils.go
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2021 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
|
||||
*
|
||||
* https://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 s2a
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
commonpb "github.com/google/s2a-go/internal/proto/common_go_proto"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/peer"
|
||||
)
|
||||
|
||||
// AuthInfo exposes security information from the S2A to the application.
|
||||
type AuthInfo interface {
|
||||
// AuthType returns the authentication type.
|
||||
AuthType() string
|
||||
// ApplicationProtocol returns the application protocol, e.g. "grpc".
|
||||
ApplicationProtocol() string
|
||||
// TLSVersion returns the TLS version negotiated during the handshake.
|
||||
TLSVersion() commonpb.TLSVersion
|
||||
// Ciphersuite returns the ciphersuite negotiated during the handshake.
|
||||
Ciphersuite() commonpb.Ciphersuite
|
||||
// PeerIdentity returns the authenticated identity of the peer.
|
||||
PeerIdentity() *commonpb.Identity
|
||||
// LocalIdentity returns the local identity of the application used during
|
||||
// session setup.
|
||||
LocalIdentity() *commonpb.Identity
|
||||
// PeerCertFingerprint returns the SHA256 hash of the peer certificate used in
|
||||
// the S2A handshake.
|
||||
PeerCertFingerprint() []byte
|
||||
// LocalCertFingerprint returns the SHA256 hash of the local certificate used
|
||||
// in the S2A handshake.
|
||||
LocalCertFingerprint() []byte
|
||||
// IsHandshakeResumed returns true if a cached session was used to resume
|
||||
// the handshake.
|
||||
IsHandshakeResumed() bool
|
||||
// SecurityLevel returns the security level of the connection.
|
||||
SecurityLevel() credentials.SecurityLevel
|
||||
}
|
||||
|
||||
// AuthInfoFromPeer extracts the authinfo.S2AAuthInfo object from the given
|
||||
// peer, if it exists. This API should be used by gRPC clients after
|
||||
// obtaining a peer object using the grpc.Peer() CallOption.
|
||||
func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {
|
||||
s2aAuthInfo, ok := p.AuthInfo.(AuthInfo)
|
||||
if !ok {
|
||||
return nil, errors.New("no S2AAuthInfo found in Peer")
|
||||
}
|
||||
return s2aAuthInfo, nil
|
||||
}
|
||||
|
||||
// AuthInfoFromContext extracts the authinfo.S2AAuthInfo object from the given
|
||||
// context, if it exists. This API should be used by gRPC server RPC handlers
|
||||
// to get information about the peer. On the client-side, use the grpc.Peer()
|
||||
// CallOption and the AuthInfoFromPeer function.
|
||||
func AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {
|
||||
p, ok := peer.FromContext(ctx)
|
||||
if !ok {
|
||||
return nil, errors.New("no Peer found in Context")
|
||||
}
|
||||
return AuthInfoFromPeer(p)
|
||||
}
|
||||
24
vendor/github.com/google/s2a-go/testdata/client_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/testdata/client_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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/testdata/client_key.pem
generated
vendored
Normal file
27
vendor/github.com/google/s2a-go/testdata/client_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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/testdata/server_cert.pem
generated
vendored
Normal file
24
vendor/github.com/google/s2a-go/testdata/server_cert.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
-----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/testdata/server_key.pem
generated
vendored
Normal file
27
vendor/github.com/google/s2a-go/testdata/server_key.pem
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----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-----
|
||||
52
vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go
generated
vendored
52
vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go
generated
vendored
|
|
@ -1,16 +1,28 @@
|
|||
// Copyright 2022 Google LLC.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// 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
|
||||
//
|
||||
// https://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 client is a cross-platform client for the signer binary (a.k.a."EnterpriseCertSigner").
|
||||
//
|
||||
// Client is a cross-platform client for the signer binary (a.k.a."EnterpriseCertSigner").
|
||||
// The signer binary is OS-specific, but exposes a standard set of APIs for the client to use.
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/rpc"
|
||||
|
|
@ -67,14 +79,16 @@ func (k *Key) CertificateChain() [][]byte {
|
|||
// Close closes the RPC connection and kills the signer subprocess.
|
||||
// Call this to free up resources when the Key object is no longer needed.
|
||||
func (k *Key) Close() error {
|
||||
if err := k.client.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close RPC connection: %w", err)
|
||||
}
|
||||
if err := k.cmd.Process.Kill(); err != nil {
|
||||
return fmt.Errorf("failed to kill signer process: %w", err)
|
||||
}
|
||||
if err := k.cmd.Wait(); err.Error() != "signal: killed" {
|
||||
return fmt.Errorf("signer process was not killed: %w", err)
|
||||
// Wait for cmd to exit and release resources. Since the process is forcefully killed, this
|
||||
// will return a non-nil error (varies by OS), which we will ignore.
|
||||
_ = k.cmd.Wait()
|
||||
// The Pipes connecting the RPC client should have been closed when the signer subprocess was killed.
|
||||
// Calling `k.client.Close()` before `k.cmd.Process.Kill()` or `k.cmd.Wait()` _will_ cause a segfault.
|
||||
if err := k.client.Close(); err.Error() != "close |0: file already closed" {
|
||||
return fmt.Errorf("failed to close RPC connection: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -84,12 +98,19 @@ func (k *Key) Public() crypto.PublicKey {
|
|||
return k.publicKey
|
||||
}
|
||||
|
||||
// Sign signs a message by encrypting a message digest, using the specified signer options.
|
||||
// Sign signs a message digest, using the specified signer options.
|
||||
func (k *Key) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) (signed []byte, err error) {
|
||||
if opts != nil && opts.HashFunc() != 0 && len(digest) != opts.HashFunc().Size() {
|
||||
return nil, fmt.Errorf("Digest length of %v bytes does not match Hash function size of %v bytes", len(digest), opts.HashFunc().Size())
|
||||
}
|
||||
err = k.client.Call(signAPI, SignArgs{Digest: digest, Opts: opts}, &signed)
|
||||
return
|
||||
}
|
||||
|
||||
// ErrCredUnavailable is a sentinel error that indicates ECP Cred is unavailable,
|
||||
// possibly due to missing config or missing binary path.
|
||||
var ErrCredUnavailable = errors.New("Cred is unavailable")
|
||||
|
||||
// Cred spawns a signer subprocess that listens on stdin/stdout to perform certificate
|
||||
// related operations, including signing messages with the private key.
|
||||
//
|
||||
|
|
@ -103,6 +124,9 @@ func Cred(configFilePath string) (*Key, error) {
|
|||
}
|
||||
enterpriseCertSignerPath, err := util.LoadSignerBinaryPath(configFilePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrConfigUnavailable) {
|
||||
return nil, ErrCredUnavailable
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
k := &Key{
|
||||
|
|
@ -147,5 +171,15 @@ func Cred(configFilePath string) (*Key, error) {
|
|||
return nil, fmt.Errorf("invalid public key type: %T", publicKey)
|
||||
}
|
||||
|
||||
switch pub := k.publicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
if pub.Size() < 256 {
|
||||
return nil, fmt.Errorf("RSA modulus size is less than 2048 bits: %v", pub.Size()*8)
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported public key type: %v", pub)
|
||||
}
|
||||
|
||||
return k, nil
|
||||
}
|
||||
|
|
|
|||
35
vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go
generated
vendored
35
vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go
generated
vendored
|
|
@ -1,17 +1,30 @@
|
|||
// 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
|
||||
//
|
||||
// https://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 util provides helper functions for the client.
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const configFileName = "enterprise_certificate_config.json"
|
||||
const configFileName = "certificate_config.json"
|
||||
|
||||
// EnterpriseCertificateConfig contains parameters for initializing signer.
|
||||
type EnterpriseCertificateConfig struct {
|
||||
|
|
@ -20,17 +33,24 @@ type EnterpriseCertificateConfig struct {
|
|||
|
||||
// Libs specifies the locations of helper libraries.
|
||||
type Libs struct {
|
||||
SignerBinary string `json:"signer_binary"`
|
||||
ECP string `json:"ecp"`
|
||||
}
|
||||
|
||||
// ErrConfigUnavailable is a sentinel error that indicates ECP config is unavailable,
|
||||
// possibly due to entire config missing or missing binary path.
|
||||
var ErrConfigUnavailable = errors.New("Config is unavailable")
|
||||
|
||||
// LoadSignerBinaryPath retrieves the path of the signer binary from the config file.
|
||||
func LoadSignerBinaryPath(configFilePath string) (path string, err error) {
|
||||
jsonFile, err := os.Open(configFilePath)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return "", ErrConfigUnavailable
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
byteValue, err := ioutil.ReadAll(jsonFile)
|
||||
byteValue, err := io.ReadAll(jsonFile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -39,9 +59,9 @@ func LoadSignerBinaryPath(configFilePath string) (path string, err error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
signerBinaryPath := config.Libs.SignerBinary
|
||||
signerBinaryPath := config.Libs.ECP
|
||||
if signerBinaryPath == "" {
|
||||
return "", errors.New("Signer binary path is missing.")
|
||||
return "", ErrConfigUnavailable
|
||||
}
|
||||
return signerBinaryPath, nil
|
||||
}
|
||||
|
|
@ -61,9 +81,8 @@ func guessHomeDir() string {
|
|||
func getDefaultConfigFileDirectory() (directory string) {
|
||||
if runtime.GOOS == "windows" {
|
||||
return filepath.Join(os.Getenv("APPDATA"), "gcloud")
|
||||
} else {
|
||||
return filepath.Join(guessHomeDir(), ".config/gcloud")
|
||||
}
|
||||
return filepath.Join(guessHomeDir(), ".config/gcloud")
|
||||
}
|
||||
|
||||
// GetDefaultConfigFilePath returns the default path of the enterprise certificate config file created by gCloud.
|
||||
|
|
|
|||
2
vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
generated
vendored
2
vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json
generated
vendored
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"v2": "2.5.1"
|
||||
"v2": "2.8.0"
|
||||
}
|
||||
|
|
|
|||
29
vendor/github.com/googleapis/gax-go/v2/CHANGES.md
generated
vendored
29
vendor/github.com/googleapis/gax-go/v2/CHANGES.md
generated
vendored
|
|
@ -1,5 +1,34 @@
|
|||
# Changelog
|
||||
|
||||
## [2.8.0](https://github.com/googleapis/gax-go/compare/v2.7.1...v2.8.0) (2023-03-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **v2:** add WithTimeout option ([#259](https://github.com/googleapis/gax-go/issues/259)) ([9a8da43](https://github.com/googleapis/gax-go/commit/9a8da43693002448b1e8758023699387481866d1))
|
||||
|
||||
## [2.7.1](https://github.com/googleapis/gax-go/compare/v2.7.0...v2.7.1) (2023-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **v2/apierror:** return Unknown GRPCStatus when err source is HTTP ([#260](https://github.com/googleapis/gax-go/issues/260)) ([043b734](https://github.com/googleapis/gax-go/commit/043b73437a240a91229207fb3ee52a9935a36f23)), refs [#254](https://github.com/googleapis/gax-go/issues/254)
|
||||
|
||||
## [2.7.0](https://github.com/googleapis/gax-go/compare/v2.6.0...v2.7.0) (2022-11-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* update google.golang.org/api to latest ([#240](https://github.com/googleapis/gax-go/issues/240)) ([f690a02](https://github.com/googleapis/gax-go/commit/f690a02c806a2903bdee943ede3a58e3a331ebd6))
|
||||
* **v2/apierror:** add apierror.FromWrappingError ([#238](https://github.com/googleapis/gax-go/issues/238)) ([9dbd96d](https://github.com/googleapis/gax-go/commit/9dbd96d59b9d54ceb7c025513aa8c1a9d727382f))
|
||||
|
||||
## [2.6.0](https://github.com/googleapis/gax-go/compare/v2.5.1...v2.6.0) (2022-10-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **v2:** copy DetermineContentType functionality ([#230](https://github.com/googleapis/gax-go/issues/230)) ([2c52a70](https://github.com/googleapis/gax-go/commit/2c52a70bae965397f740ed27d46aabe89ff249b3))
|
||||
|
||||
## [2.5.1](https://github.com/googleapis/gax-go/compare/v2.5.0...v2.5.1) (2022-08-04)
|
||||
|
||||
|
||||
|
|
|
|||
56
vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
generated
vendored
56
vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go
generated
vendored
|
|
@ -39,6 +39,7 @@ import (
|
|||
jsonerror "github.com/googleapis/gax-go/v2/apierror/internal/proto"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
|
@ -197,12 +198,12 @@ func (a *APIError) Unwrap() error {
|
|||
// Error returns a readable representation of the APIError.
|
||||
func (a *APIError) Error() string {
|
||||
var msg string
|
||||
if a.status != nil {
|
||||
msg = a.err.Error()
|
||||
} else if a.httpErr != nil {
|
||||
if a.httpErr != nil {
|
||||
// Truncate the googleapi.Error message because it dumps the Details in
|
||||
// an ugly way.
|
||||
msg = fmt.Sprintf("googleapi: Error %d: %s", a.httpErr.Code, a.httpErr.Message)
|
||||
} else if a.status != nil {
|
||||
msg = a.err.Error()
|
||||
}
|
||||
return strings.TrimSpace(fmt.Sprintf("%s\n%s", msg, a.details))
|
||||
}
|
||||
|
|
@ -233,30 +234,53 @@ func (a *APIError) Metadata() map[string]string {
|
|||
|
||||
}
|
||||
|
||||
// FromError parses a Status error or a googleapi.Error and builds an APIError.
|
||||
func FromError(err error) (*APIError, bool) {
|
||||
if err == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
ae := APIError{err: err}
|
||||
// setDetailsFromError parses a Status error or a googleapi.Error
|
||||
// and sets status and details or httpErr and details, respectively.
|
||||
// It returns false if neither Status nor googleapi.Error can be parsed.
|
||||
// When err is a googleapi.Error, the status of the returned error will
|
||||
// be set to an Unknown error, rather than nil, since a nil code is
|
||||
// interpreted as OK in the gRPC status package.
|
||||
func (a *APIError) setDetailsFromError(err error) bool {
|
||||
st, isStatus := status.FromError(err)
|
||||
var herr *googleapi.Error
|
||||
isHTTPErr := errors.As(err, &herr)
|
||||
|
||||
switch {
|
||||
case isStatus:
|
||||
ae.status = st
|
||||
ae.details = parseDetails(st.Details())
|
||||
a.status = st
|
||||
a.details = parseDetails(st.Details())
|
||||
case isHTTPErr:
|
||||
ae.httpErr = herr
|
||||
ae.details = parseHTTPDetails(herr)
|
||||
a.httpErr = herr
|
||||
a.details = parseHTTPDetails(herr)
|
||||
a.status = status.New(codes.Unknown, herr.Message)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// FromError parses a Status error or a googleapi.Error and builds an
|
||||
// APIError, wrapping the provided error in the new APIError. It
|
||||
// returns false if neither Status nor googleapi.Error can be parsed.
|
||||
func FromError(err error) (*APIError, bool) {
|
||||
return ParseError(err, true)
|
||||
}
|
||||
|
||||
// ParseError parses a Status error or a googleapi.Error and builds an
|
||||
// APIError. If wrap is true, it wraps the error in the new APIError.
|
||||
// It returns false if neither Status nor googleapi.Error can be parsed.
|
||||
func ParseError(err error, wrap bool) (*APIError, bool) {
|
||||
if err == nil {
|
||||
return nil, false
|
||||
}
|
||||
ae := APIError{}
|
||||
if wrap {
|
||||
ae = APIError{err: err}
|
||||
}
|
||||
if !ae.setDetailsFromError(err) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &ae, true
|
||||
|
||||
}
|
||||
|
||||
// parseDetails accepts a slice of interface{} that should be backed by some
|
||||
|
|
|
|||
21
vendor/github.com/googleapis/gax-go/v2/call_option.go
generated
vendored
21
vendor/github.com/googleapis/gax-go/v2/call_option.go
generated
vendored
|
|
@ -218,6 +218,14 @@ func (p pathOpt) Resolve(s *CallSettings) {
|
|||
s.Path = p.p
|
||||
}
|
||||
|
||||
type timeoutOpt struct {
|
||||
t time.Duration
|
||||
}
|
||||
|
||||
func (t timeoutOpt) Resolve(s *CallSettings) {
|
||||
s.timeout = t.t
|
||||
}
|
||||
|
||||
// WithPath applies a Path override to the HTTP-based APICall.
|
||||
//
|
||||
// This is for internal use only.
|
||||
|
|
@ -230,6 +238,15 @@ func WithGRPCOptions(opt ...grpc.CallOption) CallOption {
|
|||
return grpcOpt(append([]grpc.CallOption(nil), opt...))
|
||||
}
|
||||
|
||||
// WithTimeout is a convenience option for setting a context.WithTimeout on the
|
||||
// singular context.Context used for **all** APICall attempts. Calculated from
|
||||
// the start of the first APICall attempt.
|
||||
// If the context.Context provided to Invoke already has a Deadline set, that
|
||||
// will always be respected over the deadline calculated using this option.
|
||||
func WithTimeout(t time.Duration) CallOption {
|
||||
return &timeoutOpt{t: t}
|
||||
}
|
||||
|
||||
// CallSettings allow fine-grained control over how calls are made.
|
||||
type CallSettings struct {
|
||||
// Retry returns a Retryer to be used to control retry logic of a method call.
|
||||
|
|
@ -241,4 +258,8 @@ type CallSettings struct {
|
|||
|
||||
// Path is an HTTP override for an APICall.
|
||||
Path string
|
||||
|
||||
// Timeout defines the amount of time that Invoke has to complete.
|
||||
// Unexported so it cannot be changed by the code in an APICall.
|
||||
timeout time.Duration
|
||||
}
|
||||
|
|
|
|||
112
vendor/github.com/googleapis/gax-go/v2/content_type.go
generated
vendored
Normal file
112
vendor/github.com/googleapis/gax-go/v2/content_type.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright 2022, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package gax
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const sniffBuffSize = 512
|
||||
|
||||
func newContentSniffer(r io.Reader) *contentSniffer {
|
||||
return &contentSniffer{r: r}
|
||||
}
|
||||
|
||||
// contentSniffer wraps a Reader, and reports the content type determined by sniffing up to 512 bytes from the Reader.
|
||||
type contentSniffer struct {
|
||||
r io.Reader
|
||||
start []byte // buffer for the sniffed bytes.
|
||||
err error // set to any error encountered while reading bytes to be sniffed.
|
||||
|
||||
ctype string // set on first sniff.
|
||||
sniffed bool // set to true on first sniff.
|
||||
}
|
||||
|
||||
func (cs *contentSniffer) Read(p []byte) (n int, err error) {
|
||||
// Ensure that the content type is sniffed before any data is consumed from Reader.
|
||||
_, _ = cs.ContentType()
|
||||
|
||||
if len(cs.start) > 0 {
|
||||
n := copy(p, cs.start)
|
||||
cs.start = cs.start[n:]
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// We may have read some bytes into start while sniffing, even if the read ended in an error.
|
||||
// We should first return those bytes, then the error.
|
||||
if cs.err != nil {
|
||||
return 0, cs.err
|
||||
}
|
||||
|
||||
// Now we have handled all bytes that were buffered while sniffing. Now just delegate to the underlying reader.
|
||||
return cs.r.Read(p)
|
||||
}
|
||||
|
||||
// ContentType returns the sniffed content type, and whether the content type was successfully sniffed.
|
||||
func (cs *contentSniffer) ContentType() (string, bool) {
|
||||
if cs.sniffed {
|
||||
return cs.ctype, cs.ctype != ""
|
||||
}
|
||||
cs.sniffed = true
|
||||
// If ReadAll hits EOF, it returns err==nil.
|
||||
cs.start, cs.err = ioutil.ReadAll(io.LimitReader(cs.r, sniffBuffSize))
|
||||
|
||||
// Don't try to detect the content type based on possibly incomplete data.
|
||||
if cs.err != nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
cs.ctype = http.DetectContentType(cs.start)
|
||||
return cs.ctype, true
|
||||
}
|
||||
|
||||
// DetermineContentType determines the content type of the supplied reader.
|
||||
// The content of media will be sniffed to determine the content type.
|
||||
// After calling DetectContentType the caller must not perform further reads on
|
||||
// media, but rather read from the Reader that is returned.
|
||||
func DetermineContentType(media io.Reader) (io.Reader, string) {
|
||||
// For backwards compatibility, allow clients to set content
|
||||
// type by providing a ContentTyper for media.
|
||||
// Note: This is an anonymous interface definition copied from googleapi.ContentTyper.
|
||||
if typer, ok := media.(interface {
|
||||
ContentType() string
|
||||
}); ok {
|
||||
return media, typer.ContentType()
|
||||
}
|
||||
|
||||
sniffer := newContentSniffer(media)
|
||||
if ctype, ok := sniffer.ContentType(); ok {
|
||||
return sniffer, ctype
|
||||
}
|
||||
// If content type could not be sniffed, reads from sniffer will eventually fail with an error.
|
||||
return sniffer, ""
|
||||
}
|
||||
2
vendor/github.com/googleapis/gax-go/v2/internal/version.go
generated
vendored
2
vendor/github.com/googleapis/gax-go/v2/internal/version.go
generated
vendored
|
|
@ -30,4 +30,4 @@
|
|||
package internal
|
||||
|
||||
// Version is the current tagged release of the library.
|
||||
const Version = "2.5.1"
|
||||
const Version = "2.8.0"
|
||||
|
|
|
|||
10
vendor/github.com/googleapis/gax-go/v2/invoke.go
generated
vendored
10
vendor/github.com/googleapis/gax-go/v2/invoke.go
generated
vendored
|
|
@ -68,6 +68,16 @@ type sleeper func(ctx context.Context, d time.Duration) error
|
|||
// invoke implements Invoke, taking an additional sleeper argument for testing.
|
||||
func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error {
|
||||
var retryer Retryer
|
||||
|
||||
// Only use the value provided via WithTimeout if the context doesn't
|
||||
// already have a deadline. This is important for backwards compatibility if
|
||||
// the user already set a deadline on the context given to Invoke.
|
||||
if _, ok := ctx.Deadline(); !ok && settings.timeout != 0 {
|
||||
c, cc := context.WithTimeout(ctx, settings.timeout)
|
||||
defer cc()
|
||||
ctx = c
|
||||
}
|
||||
|
||||
for {
|
||||
err := call(ctx, settings)
|
||||
if err == nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue