diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 5655b2528..0b91f7c3b 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -5,8 +5,6 @@ env: on: pull_request: - branches: - - main push: branches: - main @@ -134,7 +132,6 @@ jobs: strategy: matrix: crypto: - - hsm - standard steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 diff --git a/.gitignore b/.gitignore index e7170d420..74c0f053f 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,9 @@ tmp-gen/ service/rttests/*.tdf coverage.out coverage.lcov +sdk/nanotest1.ntdf *.zip sensitive.txt.tdf -keys/ \ No newline at end of file +keys/ +/examples/sensitive.txt.ntdf diff --git a/Makefile b/Makefile index ea40e0ebd..a513e2db9 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ clean: build: proto-generate opentdf sdk/sdk examples/examples opentdf: $(shell find service) - go build --tags=opentdf.hsm -o opentdf -v service/main.go + go build -o opentdf -v service/main.go sdk/sdk: $(shell find sdk) (cd sdk && go build ./...) diff --git a/examples/cmd/decrypt.go b/examples/cmd/decrypt.go index dc2794127..3856bbea0 100644 --- a/examples/cmd/decrypt.go +++ b/examples/cmd/decrypt.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "io" "os" @@ -40,6 +41,7 @@ func decrypt(cmd *cobra.Command, args []string) error { } defer file.Close() + cmd.Println("# TDF") tdfreader, err := client.LoadTDF(file) if err != nil { @@ -51,6 +53,24 @@ func decrypt(cmd *cobra.Command, args []string) error { if err != nil && err != io.EOF { return err } + cmd.Println("\n-----\n\n# NANO") + + nTdfFile, err := os.Open("sensitive.txt.ntdf") + if err != nil { + return err + } + + outBuf := bytes.Buffer{} + _, err = client.ReadNanoTDF(io.Writer(&outBuf), nTdfFile) + if err != nil { + return err + } + + if "Hello Virtru" == outBuf.String() { + cmd.Println("✅ NanoTDF test passed!") + } else { + cmd.Println("❌ NanoTDF test failed!") + } return nil } diff --git a/examples/cmd/encrypt.go b/examples/cmd/encrypt.go index 0c79c6212..efc6782a7 100644 --- a/examples/cmd/encrypt.go +++ b/examples/cmd/encrypt.go @@ -1,11 +1,14 @@ package cmd import ( + "bytes" "encoding/json" "fmt" "os" "strings" + "github.com/opentdf/platform/lib/ocrypto" + "github.com/opentdf/platform/sdk" "github.com/spf13/cobra" ) @@ -64,5 +67,53 @@ func encrypt(cmd *cobra.Command, args []string) error { // Print Manifest cmd.Println(string(manifestJSON)) + + // + // NanoTDF + // + + attributes := []string{ + "https://example.com/attr/attr1/value/value1", + } + + nanoTDFCOnfig, err := client.NewNanoTDFConfig() + if err != nil { + return err + } + + nanoTDFCOnfig.SetAttributes(attributes) + nanoTDFCOnfig.SetKasURL(fmt.Sprintf("http://%s/kas", cmd.Flag("platformEndpoint").Value.String())) + + nTDFile := "sensitive.txt.ntdf" + strReader = strings.NewReader(plainText) + nTdfFile, err := os.Create(nTDFile) + defer nTdfFile.Close() + + _, err = client.CreateNanoTDF(nTdfFile, strReader, *nanoTDFCOnfig) + if err != nil { + return err + } + + err = dumpNanoTDF(cmd, nTDFile) + if err != nil { + return err + } + return nil +} + +func dumpNanoTDF(cmd *cobra.Command, nTdfFile string) error { + f, err := os.Open(nTdfFile) + if err != nil { + return err + } + + buf := bytes.Buffer{} + _, err = buf.ReadFrom(f) + if err != nil { + return err + } + + cmd.Println(string(ocrypto.Base64Encode(buf.Bytes()))) + return nil } diff --git a/examples/go.mod b/examples/go.mod index 16f33b70c..04bb60a7a 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,6 +3,7 @@ module github.com/opentdf/platform/examples go 1.21 require ( + github.com/opentdf/platform/lib/ocrypto v0.1.3 github.com/opentdf/platform/protocol/go v0.2.3 github.com/opentdf/platform/sdk v0.2.3 github.com/spf13/cobra v1.8.0 @@ -25,7 +26,6 @@ require ( github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/jwx/v2 v2.0.21 // indirect github.com/lestrrat-go/option v1.0.1 // indirect - github.com/opentdf/platform/lib/ocrypto v0.1.3 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect diff --git a/go.work.sum b/go.work.sum index 4d04cd363..54148b3c1 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,4 +1,5 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512 h1:SRsZGA7aFnCZETmov57jwPrWuTmaZK6+4R4v5FUe1/c= bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -294,35 +295,47 @@ cloud.google.com/go/websecurityscanner v1.6.5 h1:YqWZrZYabG88TZt7364XWRJGhxmxhon cloud.google.com/go/websecurityscanner v1.6.5/go.mod h1:QR+DWaxAz2pWooylsBF854/Ijvuoa3FCyS1zBa1rAVQ= cloud.google.com/go/workflows v1.12.4 h1:uHNmUiatTbPQ4H1pabwfzpfEYD4BBnqDHqMm2IesOh4= cloud.google.com/go/workflows v1.12.4/go.mod h1:yQ7HUqOkdJK4duVtMeBCAOPiN1ZF1E9pAMX51vpwB/w= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA= github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v56.3.0+incompatible h1:DmhwMrUIvpeoTDiWRDtNHqelNUd3Og8JCkrLHQK795c= github.com/Azure/azure-sdk-for-go v56.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHqeUGso5qm2BqqE= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/cosesign1go v1.1.0 h1:JnHY2wQkIK4HmstaK5rMdM4S83nIC7fJmD1phOLj9qo= github.com/Microsoft/cosesign1go v1.1.0/go.mod h1:o+sw7nhlGE6twhfjXQDWmBJO8zmfQXEmCcXEi3zha8I= @@ -353,14 +366,19 @@ github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3 h1:4FA+QBaydEHlwxg0lMN3rhwoDaQy6LKhVWR4qvq4BuA= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw= @@ -368,6 +386,7 @@ github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxk github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -376,45 +395,65 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAu github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= +github.com/alexflint/go-filemutex v1.2.0 h1:1v0TJPDtlhgpW4nJ+GvxCLSlUDC3+gW0CQQvlmfDR/s= github.com/alexflint/go-filemutex v1.2.0/go.mod h1:mYyQSWvw9Tx2/H2n9qXPb52tTYfE0pZAWcBq5mK025c= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves= github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/arrow/go/v14 v14.0.2 h1:N8OkaJEOfI3mEZt07BIkvo4sC6XDbL+48MBPWO5IONw= github.com/apache/arrow/go/v14 v14.0.2/go.mod h1:u3fgh3EdgN/YQ8cVQRguVW3R+seMybFg8QBQ5LU+eBY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.43.16 h1:Y7wBby44f+tINqJjw5fLH3vA+gFq4uMITIKqditwM14= github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bytecodealliance/wasmtime-go v0.36.0 h1:B6thr7RMM9xQmouBtUqm1RpkJjuLS37m6nxX+iwsQSc= github.com/bytecodealliance/wasmtime-go v0.36.0/go.mod h1:q320gUxqyI8yB+ZqRuaJOEnGkAnHh6WtJjMaT2CW4wI= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -423,14 +462,20 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0 h1:WW2B2uxx9KWF6bGlHqhm8Okiafwwx7Y2kcpn8lCpjgo= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= @@ -457,9 +502,13 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/container-orchestrated-devices/container-device-interface v0.6.1 h1:mz77uJoP8im/4Zins+mPqt677ZMaflhoGaYrRAl5jvA= github.com/container-orchestrated-devices/container-device-interface v0.6.1/go.mod h1:40T6oW59rFrL/ksiSs7q45GzjGlbvxnA4xaK6cyq+kA= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= @@ -468,6 +517,7 @@ github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0 h1:osn1exbzdub9L5SouXO5swW4ea/xVdJZ3wokxN5GrnA= github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= github.com/containerd/btrfs/v2 v2.0.0 h1:FN4wsx7KQrYoLXN7uLP0vBV4oVWHOIKDRQ1G2Z0oL5M= github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k= @@ -599,21 +649,26 @@ github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pABH85425Es2g= github.com/containers/ocicrypt v1.1.6 h1:uoG52u2e91RE4UqmBICZY8dNshgfvkdl3BW6jnxiFaI= github.com/containers/ocicrypt v1.1.6/go.mod h1:WgjxPWdTJMqYMjf3M6cuIFFA1/MpyyhIM99YInA+Rvc= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= @@ -621,6 +676,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -632,15 +688,22 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0 h1:suYBsYZIkSlUMEz4TAYCczKf62IA2UWC+O8+KtdOhCo= github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 h1:+CpLbZIeUn94m02LdEKPcgErLJ347NUwxPKs5u8ieiY= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 h1:itqmmf1PFpC4n5JW+j4BU7X4MTfVurhYRTjODoPb2Y8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= @@ -650,8 +713,11 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/distribution/distribution/v3 v3.0.0-20220526142353-ffbd94cbe269 h1:hbCT8ZPPMqefiAWD2ZKjn7ypokIGViTvBBg/ExLSdCk= github.com/distribution/distribution/v3 v3.0.0-20220526142353-ffbd94cbe269/go.mod h1:28YO/VJk9/64+sTGNuYaBjWxrXTPrj0C0XmgTIOjxX4= +github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -676,13 +742,18 @@ github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -701,6 +772,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= @@ -709,6 +781,7 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/foxcpp/go-mockdns v0.0.0-20210729171921-fb145fc6f897/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -716,20 +789,26 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ini/ini v1.66.6/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= @@ -749,34 +828,44 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -803,6 +892,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -821,12 +911,15 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -849,6 +942,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -866,7 +960,9 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -885,19 +981,24 @@ github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56 github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 h1:zC34cGQu69FG7qzJ3WiKW244WfhDC3xxYMeNOX2gtUQ= github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -914,6 +1015,7 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9K github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= +github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -927,6 +1029,7 @@ github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= @@ -935,25 +1038,34 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -965,16 +1077,21 @@ github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9 github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c= github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/j-keck/arping v1.0.2 h1:hlLhuXgQkzIJTZuhMigvG/CuSkaspeaD9hRDk2zuiMI= github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joefitzgerald/rainbow-reporter v0.1.0 h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josephspurrier/goversioninfo v1.4.0 h1:Puhl12NSHUSALHSuzYwPYQkqa2E1+7SrtAPJorKK0C8= github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -985,7 +1102,9 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= @@ -1007,9 +1126,11 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -1017,6 +1138,7 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= @@ -1034,7 +1156,9 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -1055,6 +1179,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= @@ -1064,19 +1189,26 @@ github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0 github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU= github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b h1:Ga1nclDSe8gOw37MVLMhfu2QKWtD6gvtQ298zsKVh8g= github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -1099,12 +1231,15 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q= github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= @@ -1112,12 +1247,16 @@ github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY= github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47 h1:4DQRPj35Y41WogBxyhOXlrI37nzGlyEcsforeudyYPQ= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/networkplumbing/go-nft v0.2.0 h1:eKapmyVUt/3VGfhYaDos5yeprm+LPt881UeksmKKZHY= github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= @@ -1134,8 +1273,10 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -1147,6 +1288,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= github.com/onsi/gomega v1.24.2/go.mod h1:gs3J10IS7Z7r7eXRoNJIrNqU4ToQukCJhFtKrWgHWnk= github.com/open-policy-agent/opa v0.42.2/go.mod h1:MrmoTi/BsKWT58kXlVayBb+rYVeaMwuBm3nYAN3923s= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1191,6 +1333,7 @@ github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaL github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/opentdf/platform/sdk v0.2.3/go.mod h1:J1oo3AvZ0sBR4rTjxG8h8H4aCu88cbINjMq7468e+9s= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= @@ -1198,11 +1341,14 @@ github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterh/liner v0.0.0-20170211195444-bf27d3ba8e1d/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1210,8 +1356,10 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= @@ -1258,6 +1406,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1274,22 +1423,30 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/safchain/ethtool v0.2.0 h1:dILxMBqDnQfX192cCAPjZr9v2IgVXeElHPy435Z/IdE= github.com/safchain/ethtool v0.2.0/go.mod h1:WkKB1DnNtvsMlDmQ50sgwowDJV/hGbJSOvJoEXs1AJQ= github.com/sagikazarmark/crypt v0.17.0 h1:ZA/7pXyjkHoK4bW4mIdnCLvL8hd+Nrbiw7Dqk7D4qUk= github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sclevine/agouti v3.0.0+incompatible h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -1300,10 +1457,13 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -1349,8 +1509,11 @@ github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPx github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -1383,6 +1546,7 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1 github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= @@ -1390,6 +1554,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -1399,8 +1564,11 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= @@ -1415,6 +1583,7 @@ go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= @@ -1429,11 +1598,15 @@ go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lL go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= +go.etcd.io/etcd/pkg/v3 v3.5.5 h1:Ablg7T7OkR+AeeeU32kdVhw/AGDsitkKPl7aW73ssjU= go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= +go.etcd.io/etcd/raft/v3 v3.5.5 h1:Ibz6XyZ60OYyRopu73lLM/P+qco3YtlZMOhnXNS051I= go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI= go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= +go.etcd.io/etcd/server/v3 v3.5.5 h1:jNjYm/9s+f9A9r6+SC4RvNaz6AqixpOvhrFdT0PvIj0= go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc= +go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= @@ -1464,9 +1637,11 @@ go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+n go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= @@ -1479,12 +1654,15 @@ go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0 h1:c5VRjxCXdQlx1HjzwGdQHzZaVI82b5EbBgOu2ljD92g= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0 h1:7ao1wpzHRVKf0OQ7GIxiQJA6X7DLX9o14gmVon7mMK8= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= @@ -1556,6 +1734,7 @@ golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnL golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1569,8 +1748,10 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -1799,6 +1980,7 @@ golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1926,6 +2108,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -2067,25 +2250,34 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -2109,6 +2301,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069z honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= @@ -2135,6 +2328,7 @@ k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= +k8s.io/code-generator v0.19.7 h1:kM/68Y26Z/u//TFc1ggVVcg62te8A2yQh57jBfD0FWQ= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= @@ -2151,6 +2345,7 @@ k8s.io/cri-api v0.27.1 h1:KWO+U8MfI9drXB/P4oU9VchaWYOlwDglJZVHWMpTT3Q= k8s.io/cri-api v0.27.1/go.mod h1:+Ts/AVYbIo04S86XbTD73UPp/DkTiYxtsFeOFEu32L0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded h1:JApXBKYyB7l9xx+DK7/+mFjC7A9Bt5A93FPvFD0HIFE= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= @@ -2159,12 +2354,15 @@ k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.26.2 h1:GM1gg3tFK3OUU/QQFi93yGjG3lJT8s8l3Wkn2+VxBLM= k8s.io/kms v0.26.2/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kubernetes v1.13.0 h1:qTfB+u5M92k2fCCCVP2iuhgwwSOv1EkAkvQY1tQODD8= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -2174,12 +2372,16 @@ k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt oras.land/oras-go v1.2.0 h1:yoKosVIbsPoFMqAIFHTnrmOuafHal+J/r+I5bdbVWu4= oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc= oras.land/oras-go/v2 v2.3.1/go.mod h1:5AQXVEu1X/FKp1F9DMOb5ZItZBOa0y5dha0yCm4NR9c= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 h1:+xBL5uTc+BkPBwmMi3vYfUJjq+N3K+H6PXeETwf5cPI= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= diff --git a/lib/ocrypto/aes_gcm.go b/lib/ocrypto/aes_gcm.go index c6e5a0285..77aaf647e 100644 --- a/lib/ocrypto/aes_gcm.go +++ b/lib/ocrypto/aes_gcm.go @@ -113,3 +113,23 @@ func (aesGcm AesGcm) DecryptWithTagSize(data []byte, authTagSize int) ([]byte, e return plainData, nil } + +// DecryptWithIVAndTagSize decrypts data with symmetric key. +// NOTE: This method expects gcm standard nonce size(12) of iv. +func (aesGcm AesGcm) DecryptWithIVAndTagSize(iv, data []byte, authTagSize int) ([]byte, error) { + if len(iv) != GcmStandardNonceSize { + return nil, errors.New("invalid nonce size, expects GcmStandardNonceSize") + } + + gcm, err := cipher.NewGCMWithTagSize(aesGcm.block, authTagSize) + if err != nil { + return nil, fmt.Errorf("cipher.NewGCMWithTagSize failed: %w", err) + } + + plainData, err := gcm.Open(nil, iv, data, nil) + if err != nil { + return nil, fmt.Errorf("gcm.Open failed: %w", err) + } + + return plainData, nil +} diff --git a/lib/ocrypto/ec_key_pair.go b/lib/ocrypto/ec_key_pair.go index b90d42ae8..a3405cb7e 100644 --- a/lib/ocrypto/ec_key_pair.go +++ b/lib/ocrypto/ec_key_pair.go @@ -1,6 +1,7 @@ package ocrypto import ( + "bytes" "crypto/ecdh" "crypto/ecdsa" "crypto/elliptic" @@ -29,9 +30,9 @@ type ECKeyPair struct { PrivateKey *ecdsa.PrivateKey } -// NewECKeyPair Generates an EC key pair of the given bit size. -func NewECKeyPair(mode ECCMode) (ECKeyPair, error) { +func getCurveFromECCMode(mode ECCMode) (elliptic.Curve, error) { var c elliptic.Curve + switch mode { case ECCModeSecp256r1: c = elliptic.P256() @@ -41,9 +42,23 @@ func NewECKeyPair(mode ECCMode) (ECKeyPair, error) { c = elliptic.P521() case ECCModeSecp256k1: // TODO FIXME - unsupported? - return ECKeyPair{}, errors.New("unsupported ec key pair mode") + return nil, errors.New("unsupported ec key pair mode") default: - return ECKeyPair{}, fmt.Errorf("invalid ec key pair mode %d", mode) + return nil, fmt.Errorf("invalid ec key pair mode %d", mode) + } + + return c, nil +} + +// NewECKeyPair Generates an EC key pair of the given bit size. +func NewECKeyPair(mode ECCMode) (ECKeyPair, error) { + var c elliptic.Curve + + var err error + + c, err = getCurveFromECCMode(mode) + if err != nil { + return ECKeyPair{}, err } privateKey, err := ecdsa.GenerateKey(c, rand.Reader) @@ -104,6 +119,18 @@ func (keyPair ECKeyPair) KeySize() (int, error) { return keyPair.PrivateKey.Params().N.BitLen(), nil } +// CompressedECPublicKey - return a compressed key from the supplied curve and public key +func CompressedECPublicKey(mode ECCMode, pubKey ecdsa.PublicKey) ([]byte, error) { + curve, err := getCurveFromECCMode(mode) + if err != nil { + return nil, fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err) + } + + compressedKey := elliptic.MarshalCompressed(curve, pubKey.X, pubKey.Y) + + return compressedKey, nil +} + // ConvertToECDHPublicKey convert the ec public key to ECDH public key func ConvertToECDHPublicKey(key interface{}) (*ecdh.PublicKey, error) { switch k := key.(type) { @@ -133,10 +160,10 @@ func ConvertToECDHPrivateKey(key interface{}) (*ecdh.PrivateKey, error) { } // CalculateHKDF generate a key using key derivation function. -func CalculateHKDF(salt []byte, secret []byte, keyLen int) ([]byte, error) { +func CalculateHKDF(salt []byte, secret []byte) ([]byte, error) { hkdfObj := hkdf.New(sha256.New, secret, salt, nil) - derivedKey := make([]byte, keyLen) + derivedKey := make([]byte, len(secret)) _, err := io.ReadFull(hkdfObj, derivedKey) if err != nil { return nil, fmt.Errorf("failed to derive hkdf key: %w", err) @@ -222,3 +249,80 @@ func ComputeECDHKey(privateKeyInPem []byte, publicKeyInPem []byte) ([]byte, erro return sharedKey, nil } + +func ComputeECDHKeyFromEC(publicKey *ecdsa.PublicKey, privateKey *ecdsa.PrivateKey) ([]byte, error) { + ecdhPrivateKey, err := ConvertToECDHPrivateKey(privateKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.ECPrivateKeyFromPem failed: %w", err) + } + + ecdhPublicKey, err := ConvertToECDHPublicKey(publicKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.ECPubKeyFromPem failed: %w", err) + } + + sharedKey, err := ecdhPrivateKey.ECDH(ecdhPublicKey) + if err != nil { + return nil, fmt.Errorf("there was a problem deriving a shared ECDH key: %w", err) + } + + return sharedKey, nil +} + +func ComputeECDHKeyFromECDHKeys(publicKey *ecdh.PublicKey, privateKey *ecdh.PrivateKey) ([]byte, error) { + sharedKey, err := privateKey.ECDH(publicKey) + if err != nil { + return nil, fmt.Errorf("there was a problem deriving a shared ECDH key: %w", err) + } + + return sharedKey, nil +} + +// TODO FIXME +func GetPEMPublicKeyFromPrivateKey(_ /*key*/ []byte, _ /*mode*/ ECCMode) ecdsa.PublicKey { + b := ecdsa.PublicKey{} + return b +} + +// TODO FIXME +const ( + kDummyLength = 128 +) + +func ComputeECDSASig(_ /*digest*/ [32]byte, _ /*key*/ []byte) []byte { + b := bytes.NewBuffer(make([]byte, 0, kDummyLength)) + return b.Bytes() +} + +// ECPrivateKeyInPemFormat Returns private key in pem format. +func ECPrivateKeyInPemFormat(privateKey ecdsa.PrivateKey) (string, error) { + privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey) + if err != nil { + return "", fmt.Errorf("x509.MarshalPKCS8PrivateKey failed: %w", err) + } + + privateKeyPem := pem.EncodeToMemory( + &pem.Block{ + Type: "PRIVATE KEY", + Bytes: privateKeyBytes, + }, + ) + return string(privateKeyPem), nil +} + +// ECPublicKeyInPemFormat Returns public key in pem format. +func ECPublicKeyInPemFormat(publicKey ecdsa.PublicKey) (string, error) { + publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) + if err != nil { + return "", fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err) + } + + publicKeyPem := pem.EncodeToMemory( + &pem.Block{ + Type: "PUBLIC KEY", + Bytes: publicKeyBytes, + }, + ) + + return string(publicKeyPem), nil +} diff --git a/lib/ocrypto/ec_key_pair_test.go b/lib/ocrypto/ec_key_pair_test.go index 03036ca80..6039d0adc 100644 --- a/lib/ocrypto/ec_key_pair_test.go +++ b/lib/ocrypto/ec_key_pair_test.go @@ -94,13 +94,13 @@ func TestNanoTDFRewrapKeyGenerate(t *testing.T) { digest := sha256.New() digest.Write([]byte("L1L")) - kasSymmetricKey, err := CalculateHKDF(digest.Sum(nil), kasECDHKey, 32) + kasSymmetricKey, err := CalculateHKDF(digest.Sum(nil), kasECDHKey) require.NoError(t, err, "fail to calculate HKDF key") sdkECDHKey, err := ComputeECDHKey([]byte(sdkPrivateKeyAsPem), []byte(kasPubKeyAsPem)) require.NoError(t, err, "fail to calculate ecdh key") - sdkSymmetricKey, err := CalculateHKDF(digest.Sum(nil), sdkECDHKey, 32) + sdkSymmetricKey, err := CalculateHKDF(digest.Sum(nil), sdkECDHKey) require.NoError(t, err, "fail to calculate HKDF key") if string(kasSymmetricKey) != string(sdkSymmetricKey) { diff --git a/opentdf-dev.yaml b/opentdf-dev.yaml index 7a6c9ce94..db7efc956 100644 --- a/opentdf-dev.yaml +++ b/opentdf-dev.yaml @@ -40,16 +40,95 @@ server: ## Maps the external role to the opentdf role ## Note: left side is used in the policy, right side is the external role map: - # readonly: opentdf-readonly - # admin: opentdf-admin - # org-admin: opentdf-org-admin + readonly: opentdf-readonly + admin: opentdf-admin + user: default-roles-opentdf + org-admin: opentdf-org-admin ## Custom policy (see examples https://github.com/casbin/casbin/tree/master/examples) - csv: #| - # p, role:org-admin, policy:attributes, *, *, allow - # p, role:org-admin, policy:subject-mappings, *, *, allow - # p, role:org-admin, policy:resource-mappings, *, *, allow - # p, role:org-admin, policy:kas-registry, *, *, allow + csv: | + ## Roles (prefixed with role:) + # org-admin - organization admin + # admin - admin + # readonly - readonly + # user - rewrap + # unknown - unknown role or no role + ## Actions + # read - read the resource + # write - write to the resource + # delete - delete the resource + # unsafe - unsafe actions + + # Role: user + p, role:user, kas.AccessService/PublicKey, read, allow + p, role:user, kas.AccessService/Rewrap, write, allow + p, role:user, /, read, allow + p, role:user, /kas/kas_public_key, read, allow + p, role:user, /kas/v2/kas_public_key, read, allow + p, role:user, /kas/v2/rewrap, write, allow + p, role:user, /entityresolution/resolve, write, allow + + # Role: Org-Admin + ## gRPC routes + p, role:org-admin, policy.*, *, allow + p, role:org-admin, kasregistry.*, *, allow + p, role:org-admin, kas.AccessService/LegacyPublicKey, *, allow + p, role:org-admin, kas.AccessService/PublicKey, *, allow + p, role:org-admin, kas.AccessService/Rewrap, *, allow + ## HTTP routes + p, role:org-admin, /health, *, allow + p, role:org-admin, /attributes*, *, allow + p, role:org-admin, /namespaces*, *, allow + p, role:org-admin, /subject-mappings*, *, allow + p, role:org-admin, /resource-mappings*, *, allow + p, role:org-admin, /key-access-servers*, *, allow + p, role:org-admin, /kas.AccessService/LegacyPublicKey, *, allow + # add unsafe actions to the org-admin role + + # Role: Admin + ## gRPC routes + p, role:admin, policy.*, *, allow + p, role:admin, kasregistry.*, *, allow + p, role:admin, kas.AccessService/Info, *, allow + p, role:admin, kas.AccessService/Rewrap, *, allow + p, role:admin, kas.AccessService/LegacyPublicKey, *, allow + p, role:admin, kas.AccessService/PublicKey, *, allow + ## HTTP routes + p, role:admin, /health, *, allow + p, role:admin, /attributes*, *, allow + p, role:admin, /namespaces*, *, allow + p, role:admin, /subject-mappings*, *, allow + p, role:admin, /resource-mappings*, *, allow + p, role:admin, /key-access-servers*, *, allow + p, role:admin, /kas.AccessService/LegacyPublicKey, *, allow + + ## Role: Readonly + ## gRPC routes + p, role:readonly, policy.*, read, allow + p, role:readonly, kasregistry.*, read, allow + p, role:readonly, kas.AccessService/Info, *, allow + p, role:readonly, kas.AccessService/Rewrap, *, allow + p, role:readonly, kas.AccessService/LegacyPublicKey, *, allow + p, role:readonly, kas.AccessService/PublicKey, *, allow + ## HTTP routes + p, role:readonly, /health, read, allow + p, role:readonly, /attributes*, read, allow + p, role:readonly, /namespaces*, read, allow + p, role:readonly, /subject-mappings*, read, allow + p, role:readonly, /resource-mappings*, read, allow + p, role:readonly, /key-access-servers*, read, allow + p, role:readonly, /kas.AccessService/LegacyPublicKey, read, allow + + # Public routes + ## gRPC routes + p, role:unknown, kas.AccessService/LegacyPublicKey, other, allow + p, role:unknown, kas.AccessService/PublicKey, other, allow + ## HTTP routes + p, role:unknown, /health, read, allow + p, role:unknown, /kas/v2/kas_public_key, read, allow + p, role:unknown, /kas/kas_public_key, read, allow + p, role:unknown, /entityresolution/resolve, write, allow + ## Custom model (see https://casbin.org/docs/syntax-for-models/) model: #| # [request_definition] diff --git a/sdk/kas_client.go b/sdk/kas_client.go index f252657ea..2910f5a9a 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -108,6 +108,125 @@ func (k *KASClient) unwrap(keyAccess KeyAccess, policy string) ([]byte, error) { return key, nil } +func (k *KASClient) getNanoTDFRewrapRequest(header string, kasURL string, pubKey string) (*kas.RewrapRequest, error) { + kAccess := keyAccess{ + Header: header, + KeyAccessType: "remote", + URL: kasURL, + Protocol: "kas", + } + + requestBody := requestBody{ + Algorithm: "ec:secp256r1", + KeyAccess: kAccess, + ClientPublicKey: pubKey, + } + + requestBodyJSON, err := json.Marshal(requestBody) + if err != nil { + return nil, fmt.Errorf("Error marshaling request body: %w", err) + } + + tok, err := jwt.NewBuilder(). + Claim("requestBody", string(requestBodyJSON)). + IssuedAt(time.Now()). + Expiration(time.Now().Add(secondsPerMinute * time.Second)). + Build() + + if err != nil { + return nil, fmt.Errorf("failed to create jwt: %w", err) + } + + signedToken, err := k.accessTokenSource.MakeToken(func(key jwk.Key) ([]byte, error) { + signed, err := jwt.Sign(tok, jwt.WithKey(key.Algorithm(), key)) + if err != nil { + return nil, fmt.Errorf("error signing DPoP token: %w", err) + } + + return signed, nil + }) + + if err != nil { + return nil, fmt.Errorf("failed to sign the token: %w", err) + } + + rewrapRequest := kas.RewrapRequest{ + SignedRequestToken: string(signedToken), + } + return &rewrapRequest, nil +} + +func (k *KASClient) makeNanoTDFRewrapRequest(header string, kasURL string, pubKey string) (*kas.RewrapResponse, error) { + rewrapRequest, err := k.getNanoTDFRewrapRequest(header, kasURL, pubKey) + if err != nil { + return nil, err + } + grpcAddress, err := getGRPCAddress(kasURL) + if err != nil { + return nil, err + } + + conn, err := grpc.Dial(grpcAddress, k.dialOptions...) + if err != nil { + return nil, fmt.Errorf("error connecting to kas: %w", err) + } + defer conn.Close() + + ctx := context.Background() + serviceClient := kas.NewAccessServiceClient(conn) + + response, err := serviceClient.Rewrap(ctx, rewrapRequest) + if err != nil { + return nil, fmt.Errorf("error making rewrap request: %w", err) + } + + return response, nil +} + +func (k *KASClient) unwrapNanoTDF(header string, kasURL string) ([]byte, error) { + keypair, err := ocrypto.NewECKeyPair(ocrypto.ECCModeSecp256r1) + if err != nil { + return nil, fmt.Errorf("ocrypto.NewECKeyPair failed :%w", err) + } + + publicKeyAsPem, err := keypair.PublicKeyInPemFormat() + if err != nil { + return nil, fmt.Errorf("ocrypto.NewECKeyPair.PublicKeyInPemFormat failed :%w", err) + } + + privateKeyAsPem, err := keypair.PrivateKeyInPemFormat() + if err != nil { + return nil, fmt.Errorf("ocrypto.NewECKeyPair.PrivateKeyInPemFormat failed :%w", err) + } + + response, err := k.makeNanoTDFRewrapRequest(header, kasURL, publicKeyAsPem) + if err != nil { + return nil, fmt.Errorf("error making request to kas: %w", err) + } + + sessionKey, err := ocrypto.ComputeECDHKey([]byte(privateKeyAsPem), []byte(response.GetSessionPublicKey())) + if err != nil { + return nil, fmt.Errorf("ocrypto.ComputeECDHKey failed :%w", err) + } + + sessionKey, err = ocrypto.CalculateHKDF(versionSalt(), sessionKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) + } + + aesGcm, err := ocrypto.NewAESGcm(sessionKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + symmetricKey, err := aesGcm.Decrypt(response.GetEntityWrappedKey()) + if err != nil { + return nil, fmt.Errorf("AesGcm.Decrypt failed:%w", err) + } + + return symmetricKey, nil +} + func getGRPCAddress(kasURL string) (string, error) { parsedURL, err := url.Parse(kasURL) if err != nil { diff --git a/sdk/nanotdf.go b/sdk/nanotdf.go index efb8e8e38..7e0d7389b 100644 --- a/sdk/nanotdf.go +++ b/sdk/nanotdf.go @@ -1,227 +1,790 @@ -//nolint:gomnd // nanotdf magics and lengths are inlined for clarity package sdk import ( + "bytes" + "context" + "crypto/sha256" "encoding/binary" + "encoding/json" "errors" + "fmt" "io" + "log/slog" "github.com/opentdf/platform/lib/ocrypto" + "github.com/opentdf/platform/protocol/go/kas" + "google.golang.org/grpc" ) +// ============================================================================================================ +// Support for nanoTDF operations +// +// See also the nanotdf_config.go interface +// +// ============================================================================================================ + +// / Constants const ( - ErrNanoTdfRead = Error("nanotdf read error") + kMaxTDFSize = ((16 * 1024 * 1024) - 3 - 32) //nolint:gomnd // 16 mb - 3(iv) - 32(max auth tag) + // kDatasetMaxMBBytes = 2097152 // 2mb + + // Max size of the encrypted tdfs + // 16mb payload + // ~67kb of policy + // 133 of signature + // kMaxEncryptedNTDFSize = (16 * 1024 * 1024) + (68 * 1024) + 133 //nolint:gomnd // See comment block above + + kIvPadding = 9 + kNanoTDFIvSize = 3 + kNanoTDFGMACLength = 8 + kNanoTDFMagicStringAndVersion = "L1L" ) -type NanoTdf struct { - magicNumber [3]byte - kasURL *resourceLocator - binding *bindingCfg - sigCfg *signatureConfig - policy *policyInfo - EphemeralPublicKey *eccKey +/******************************** Header************************** + | Section | Minimum Length (B) | Maximum Length (B) | + |--------------------|---------------------|---------------------| + | Magic Number | 2 | 2 | + | Version | 1 | 1 | + | KAS | 3 | 257 | + | ECC Mode | 1 | 1 | + | Payload + Sig Mode | 1 | 1 | + | Policy | 3 | 257 | + | Ephemeral Key | 33 | 67 | + ********************************* Header*************************/ + +type NanoTDFHeader struct { + kasURL ResourceLocator + bindCfg bindingConfig + sigCfg signatureConfig + EphemeralKey []byte + EncryptedPolicyBody []byte + PolicyBinding []byte } -type resourceLocator struct { - protocol urlProtocol - lengthBody uint8 - body string +// GetCipher -- get the cipher from the nano tdf header +func (header *NanoTDFHeader) GetCipher() CipherMode { + return header.sigCfg.cipher } -func (resourceLocator) isPolicyBody() {} +// ============================================================================================================ -type bindingCfg struct { - useEcdsaBinding bool - padding uint8 - bindingBody ocrypto.ECCMode +// embeddedPolicy - policy for data that is stored locally within the nanoTDF +type embeddedPolicy struct { + lengthBody uint16 + body []byte } -type signatureConfig struct { - hasSignature bool - signatureMode ocrypto.ECCMode - cipher cipherMode -} +// getLength - size in bytes of the serialized content of this object +// func (ep *embeddedPolicy) getLength() uint16 { +// const ( +// kUint16Len = 2 +// ) +// return uint16(kUint16Len /* length word length */ + len(ep.body) /* body data length */) +// } + +// writeEmbeddedPolicy - writes the content of the to the supplied writer +func (ep embeddedPolicy) writeEmbeddedPolicy(writer io.Writer) error { + // store uint16 in big endian format + const ( + kUint16Len = 2 + ) + buf := make([]byte, kUint16Len) + binary.BigEndian.PutUint16(buf, ep.lengthBody) + if _, err := writer.Write(buf); err != nil { + return err + } + slog.Debug("writeEmbeddedPolicy", slog.Uint64("policy length", uint64(ep.lengthBody))) + + if _, err := writer.Write(ep.body); err != nil { + return err + } + slog.Debug("writeEmbeddedPolicy", slog.Uint64("policy body", uint64(len(ep.body)))) -type PolicyBody interface { - isPolicyBody() // marker method to ensure interface implementation + return nil } -type policyInfo struct { - mode uint8 - body PolicyBody - binding *eccSignature +// readEmbeddedPolicy - reads an embeddedPolicy from the supplied reader +func (ep *embeddedPolicy) readEmbeddedPolicy(reader io.Reader) error { + if err := binary.Read(reader, binary.BigEndian, &ep.lengthBody); err != nil { + return errors.Join(ErrNanoTDFHeaderRead, err) + } + body := make([]byte, ep.lengthBody) + if err := binary.Read(reader, binary.BigEndian, &body); err != nil { + return errors.Join(ErrNanoTDFHeaderRead, err) + } + ep.body = body + return nil } +// ============================================================================================================ + +// remotePolicy - locator value for policy content that is stored externally to the nanoTDF type remotePolicy struct { - url *resourceLocator + url ResourceLocator } -func (remotePolicy) isPolicyBody() {} +// getLength - size in bytes of the serialized content of this object +// func (rp *remotePolicy) getLength() uint16 { +// return rp.url.getLength() +// } -type embeddedPolicy struct { - lengthBody uint16 - body string -} +// ============================================================================================================ -func (embeddedPolicy) isPolicyBody() {} +type bindingConfig struct { + useEcdsaBinding bool + padding uint8 + eccMode ocrypto.ECCMode +} -type eccSignature struct { - value []byte +type signatureConfig struct { + hasSignature bool + signatureMode ocrypto.ECCMode + cipher CipherMode } -type eccKey struct { - Key []byte +type policyInfo struct { + body PolicyBody + // binding *eccSignature } -type urlProtocol uint8 +// type eccSignature struct { +// value []byte +// } -const ( - urlProtocolHTTP urlProtocol = 0 - urlProtocolHTTPS urlProtocol = 1 - urlProtocolShared urlProtocol = 255 -) +// type eccKey struct { +// Key []byte +// } -type cipherMode int +type CipherMode int const ( - cipherModeAes256gcm64Bit cipherMode = 0 - cipherModeAes256gcm96Bit cipherMode = 1 - cipherModeAes256gcm104Bit cipherMode = 2 - cipherModeAes256gcm112Bit cipherMode = 3 - cipherModeAes256gcm120Bit cipherMode = 4 - cipherModeAes256gcm128Bit cipherMode = 5 + cipherModeAes256gcm64Bit CipherMode = 0 + cipherModeAes256gcm96Bit CipherMode = 1 + cipherModeAes256gcm104Bit CipherMode = 2 + cipherModeAes256gcm112Bit CipherMode = 3 + cipherModeAes256gcm120Bit CipherMode = 4 + cipherModeAes256gcm128Bit CipherMode = 5 ) -type policyType uint8 - const ( - policyTypeRemotePolicy policyType = 0 - policyTypEmbeddedPolicyPainText policyType = 1 - policyTypeEmbeddedPolicyEncrypted policyType = 2 - policyTypeEmbeddedPolicyEncryptedPolicyKeyAccess policyType = 3 + ErrNanoTDFHeaderRead = Error("nanoTDF read error") ) -func deserializeBindingCfg(b byte) *bindingCfg { - cfg := bindingCfg{} - cfg.useEcdsaBinding = (b >> 7 & 0x01) == 1 +// Binding config byte format +// --------------------------------- +// | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | +// --------------------------------- +// | E | M | M | M | x | x | x | x | +// --------------------------------- +// bit 8 - use ECDSA +// bit 5-7 - eccMode +// bit 1-4 - padding + +// deserializeBindingCfg - read byte of binding config into bindingConfig struct +func deserializeBindingCfg(b byte) bindingConfig { + cfg := bindingConfig{} + // Shift to low nybble test low bit + cfg.useEcdsaBinding = (b >> 7 & 0b00000001) == 1 //nolint:gomnd // better readability as literal + // ignore padding cfg.padding = 0 - cfg.bindingBody = ocrypto.ECCMode((b >> 4) & 0x07) + // shift to low nybble and use low 3 bits + cfg.eccMode = ocrypto.ECCMode((b >> 4) & 0b00000111) //nolint:gomnd // better readability as literal - return &cfg + return cfg } -func deserializeSignatureCfg(b byte) *signatureConfig { +// serializeBindingCfg - take info from bindingConfig struct and encode as single byte +func serializeBindingCfg(bindCfg bindingConfig) byte { + var bindSerial byte = 0x00 + + // Set high bit if ecdsa binding is enabled + if bindCfg.useEcdsaBinding { + bindSerial |= 0b10000000 + } + // Mask value to low 3 bytes and shift to high nybble + bindSerial |= (byte(bindCfg.eccMode) & 0b00000111) << 4 //nolint:gomnd // better readability as literal + + return bindSerial +} + +// Signature config byte format +// --------------------------------- +// | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | +// --------------------------------- +// | S | M | M | M | C | C | C | C | +// --------------------------------- +// bit 8 - has signature +// bit 5-7 - eccMode +// bit 1-4 - cipher + +// deserializeSignatureCfg - decode byte of signature config into signatureCfg struct +func deserializeSignatureCfg(b byte) signatureConfig { cfg := signatureConfig{} - cfg.hasSignature = (b >> 7 & 0x01) == 1 - cfg.signatureMode = ocrypto.ECCMode((b >> 4) & 0x07) - cfg.cipher = cipherMode(b & 0x0F) - - return &cfg -} - -func readPolicyBody(reader io.Reader, mode uint8) (PolicyBody, error) { - switch mode { - case 0: - var resourceLoc resourceLocator - if err := binary.Read(reader, binary.BigEndian, &resourceLoc.protocol); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) - } - if err := binary.Read(reader, binary.BigEndian, &resourceLoc.lengthBody); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) - } - body := make([]byte, resourceLoc.lengthBody) - if err := binary.Read(reader, binary.BigEndian, &body); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) - } - resourceLoc.body = string(body) - return remotePolicy{url: &resourceLoc}, nil - default: - var embedPolicy embeddedPolicy - if err := binary.Read(reader, binary.BigEndian, &embedPolicy.lengthBody); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) - } - body := make([]byte, embedPolicy.lengthBody) - if err := binary.Read(reader, binary.BigEndian, &body); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) - } - embedPolicy.body = string(body) - return embedPolicy, nil + // Shift high bit down and mask to test for value + cfg.hasSignature = (b >> 7 & 0b000000001) == 1 //nolint:gomnd // better readability as literal + // Shift high nybble down and mask for eccmode value + cfg.signatureMode = ocrypto.ECCMode((b >> 4) & 0b00000111) //nolint:gomnd // better readability as literal + // Mask low nybble for cipher value + cfg.cipher = CipherMode(b & 0b00001111) //nolint:gomnd // better readability as literal + + return cfg +} + +// serializeSignatureCfg - take info from signatureConfig struct and encode as single byte +func serializeSignatureCfg(sigCfg signatureConfig) byte { + var sigSerial byte = 0x00 + + // Set high bit if signature is enabled + if sigCfg.hasSignature { + sigSerial |= 0b10000000 } + // Mask low 3 bits of mode and shift to high nybble + sigSerial |= byte((sigCfg.signatureMode)&0b00000111) << 4 //nolint:gomnd // better readability as literal + // Mask low nybble of cipher + sigSerial |= byte((sigCfg.cipher) & 0b00001111) //nolint:gomnd // better readability as literal + + return sigSerial } -func readEphemeralPublicKey(reader io.Reader, curve ocrypto.ECCMode) (*eccKey, error) { +// ============================================================================================================ +// ECC info +// ============================================================================================================ + +// Key length sizes for different curves +const ( + kCurveSecp256r1KeySize = 33 + kCurveSecp256k1KeySize = 33 + kCurveSecp384r1KeySize = 49 + kCurveSecp521r1KeySize = 67 +) + +// getECCKeyLength - return the length in bytes of a key related to the specified curve +func getECCKeyLength(curve ocrypto.ECCMode) (uint8, error) { var numberOfBytes uint8 switch curve { case ocrypto.ECCModeSecp256r1: - numberOfBytes = 33 + numberOfBytes = kCurveSecp256r1KeySize case ocrypto.ECCModeSecp256k1: - numberOfBytes = 33 + numberOfBytes = kCurveSecp256k1KeySize case ocrypto.ECCModeSecp384r1: - numberOfBytes = 49 + numberOfBytes = kCurveSecp384r1KeySize case ocrypto.ECCModeSecp521r1: - numberOfBytes = 67 + numberOfBytes = kCurveSecp521r1KeySize + default: + return 0, fmt.Errorf("unknown cipher mode:%d", curve) } - buffer := make([]byte, numberOfBytes) - if err := binary.Read(reader, binary.BigEndian, &buffer); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + return numberOfBytes, nil +} + +// ============================================================================================================ +// Auth Tag info +// ============================================================================================================ + +// auth tag size in bytes for different ciphers +const ( + kCipher64AuthTagSize = 8 + kCipher96AuthTagSize = 12 + kCipher104AuthTagSize = 13 + kCipher112AuthTagSize = 14 + kCipher120AuthTagSize = 15 + kCipher128AuthTagSize = 16 +) + +// SizeOfAuthTagForCipher - Return the size in bytes of auth tag to be used for aes gcm encryption +func SizeOfAuthTagForCipher(cipherType CipherMode) (int, error) { + var numberOfBytes int + switch cipherType { + case cipherModeAes256gcm64Bit: + + numberOfBytes = kCipher64AuthTagSize + case cipherModeAes256gcm96Bit: + + numberOfBytes = kCipher96AuthTagSize + case cipherModeAes256gcm104Bit: + numberOfBytes = kCipher104AuthTagSize + case cipherModeAes256gcm112Bit: + + numberOfBytes = kCipher112AuthTagSize + case cipherModeAes256gcm120Bit: + + numberOfBytes = kCipher120AuthTagSize + case cipherModeAes256gcm128Bit: + + numberOfBytes = kCipher128AuthTagSize + default: + + return 0, fmt.Errorf("unknown cipher mode:%d", cipherType) } - return &eccKey{Key: buffer}, nil + return numberOfBytes, nil } -func ReadNanoTDFHeader(reader io.Reader) (*NanoTdf, error) { - var nanoTDF NanoTdf +// ============================================================================================================ +// NanoTDF Header read/write +// ============================================================================================================ + +func writeNanoTDFHeader(writer io.Writer, config NanoTDFConfig) ([]byte, uint32, error) { + var totalBytes uint32 + + // Write the magic number + l, err := writer.Write([]byte(kNanoTDFMagicStringAndVersion)) + if err != nil { + return nil, 0, err + } + totalBytes += uint32(l) + + slog.Debug("writeNanoTDFHeader", slog.Uint64("magic number", uint64(len(kNanoTDFMagicStringAndVersion)))) - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.magicNumber); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + // Write the kas url + err = config.kasURL.writeResourceLocator(writer) + if err != nil { + return nil, 0, err } + totalBytes += uint32(config.kasURL.getLength()) + slog.Debug("writeNanoTDFHeader", slog.Uint64("resource locator number", uint64(config.kasURL.getLength()))) - nanoTDF.kasURL = &resourceLocator{} - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.kasURL.protocol); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + // Write ECC And Binding Mode + l, err = writer.Write([]byte{serializeBindingCfg(config.bindCfg)}) + if err != nil { + return nil, 0, err } - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.kasURL.lengthBody); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + totalBytes += uint32(l) + + // Write Payload and Sig Mode + l, err = writer.Write([]byte{serializeSignatureCfg(config.sigCfg)}) + if err != nil { + return nil, 0, err } - body := make([]byte, nanoTDF.kasURL.lengthBody) - if err := binary.Read(reader, binary.BigEndian, &body); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + totalBytes += uint32(l) + + // Write policy - (Policy Mode, Policy length, Policy cipherText, Policy binding) + config.policy.body.mode = policyTypeEmbeddedPolicyEncrypted + l, err = writer.Write([]byte{byte(config.policy.body.mode)}) + if err != nil { + return nil, 0, err } - nanoTDF.kasURL.body = string(body) + totalBytes += uint32(l) - var bindingByte uint8 - if err := binary.Read(reader, binary.BigEndian, &bindingByte); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + policyObj, err := createPolicyObject(config.attributes) + if err != nil { + return nil, 0, fmt.Errorf("fail to create policy object:%w", err) } - nanoTDF.binding = deserializeBindingCfg(bindingByte) - var signatureByte uint8 - if err := binary.Read(reader, binary.BigEndian, &signatureByte); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + policyObjectAsStr, err := json.Marshal(policyObj) + if err != nil { + return nil, 0, fmt.Errorf("json.Marshal failed:%w", err) } - nanoTDF.sigCfg = deserializeSignatureCfg(signatureByte) - nanoTDF.policy = &policyInfo{} - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.policy.mode); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + ecdhKey, err := ocrypto.ConvertToECDHPrivateKey(config.keyPair.PrivateKey) + if err != nil { + return nil, 0, fmt.Errorf("ocrypto.ConvertToECDHPrivateKey failed:%w", err) } - policyBody, err := readPolicyBody(reader, nanoTDF.policy.mode) + + symKey, err := ocrypto.ComputeECDHKeyFromECDHKeys(config.kasPublicKey, ecdhKey) if err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + return nil, 0, fmt.Errorf("ocrypto.ComputeECDHKeyFromEC failed:%w", err) } - nanoTDF.policy.body = policyBody + salt := versionSalt() - nanoTDF.policy.binding = &eccSignature{} - nanoTDF.policy.binding.value = make([]byte, 8) - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.policy.binding.value); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + symmetricKey, err := ocrypto.CalculateHKDF(salt, symKey) + if err != nil { + return nil, 0, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) } - nanoTDF.EphemeralPublicKey = &eccKey{} - if err := binary.Read(reader, binary.BigEndian, &nanoTDF.EphemeralPublicKey.Key); err != nil { - return nil, errors.Join(ErrNanoTdfRead, err) + encoded := ocrypto.Base64Encode(symmetricKey) + slog.Debug("writeNanoTDFHeader", slog.String("symmetricKey", string(encoded))) + + aesGcm, err := ocrypto.NewAESGcm(symmetricKey) + if err != nil { + return nil, 0, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) } - nanoTDF.EphemeralPublicKey, err = readEphemeralPublicKey(reader, nanoTDF.binding.bindingBody) - return &nanoTDF, err + tagSize, err := SizeOfAuthTagForCipher(config.sigCfg.cipher) + if err != nil { + return nil, 0, fmt.Errorf("SizeOfAuthTagForCipher failed:%w", err) + } + + const ( + kIvLength = 12 + ) + iv := make([]byte, kIvLength) + cipherText, err := aesGcm.EncryptWithIVAndTagSize(iv, policyObjectAsStr, tagSize) + if err != nil { + return nil, 0, fmt.Errorf("AesGcm.EncryptWithIVAndTagSize failed:%w", err) + } + + embeddedP := embeddedPolicy{ + lengthBody: uint16(len(cipherText) - len(iv)), + body: cipherText[len(iv):], + } + err = embeddedP.writeEmbeddedPolicy(writer) + if err != nil { + return nil, 0, fmt.Errorf("writeEmbeddedPolicy failed:%w", err) + } + + // size of uint16 + const ( + kSizeOfUint16 = 2 + ) + totalBytes += kSizeOfUint16 + uint32(len(embeddedP.body)) + + digest := ocrypto.CalculateSHA256(embeddedP.body) + binding := digest[len(digest)-kNanoTDFGMACLength:] + l, err = writer.Write(binding) + if err != nil { + return nil, 0, err + } + totalBytes += uint32(l) + + ephemeralPublicKeyKey, _ := ocrypto.CompressedECPublicKey(config.bindCfg.eccMode, config.keyPair.PrivateKey.PublicKey) + + l, err = writer.Write(ephemeralPublicKeyKey) + if err != nil { + return nil, 0, err + } + totalBytes += uint32(l) + + return symmetricKey, totalBytes, nil +} + +func NewNanoTDFHeaderFromReader(reader io.Reader) (NanoTDFHeader, uint32, error) { + header := NanoTDFHeader{} + var size uint32 + + magicNumber := make([]byte, len(kNanoTDFMagicStringAndVersion)) + l, err := reader.Read(magicNumber) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + if magicNumber[0] != kNanoTDFMagicStringAndVersion[0] || magicNumber[1] != kNanoTDFMagicStringAndVersion[1] || magicNumber[2] != kNanoTDFMagicStringAndVersion[2] { + return header, 0, fmt.Errorf(" io.Reader.Read magic number failed : %w", err) + } + size += uint32(l) + + if string(magicNumber) != kNanoTDFMagicStringAndVersion { + return header, 0, fmt.Errorf("not a valid nano tdf") + } + + // read resource locator + resource, err := NewResourceLocatorFromReader(reader) + if err != nil { + return header, 0, fmt.Errorf("call to NewResourceLocatorFromReader failed :%w", err) + } + size += uint32(resource.getLength()) + header.kasURL = *resource + + slog.Debug("NewNanoTDFHeaderFromReader", slog.Uint64("resource locator", uint64(resource.getLength()))) + + // read ECC and Binding Mode + oneBytes := make([]byte, 1) + l, err = reader.Read(oneBytes) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + header.bindCfg = deserializeBindingCfg(oneBytes[0]) + + // check ephemeral ECC Params Enum + if header.bindCfg.eccMode != ocrypto.ECCModeSecp256r1 { + return header, 0, fmt.Errorf("current implementation of nano tdf only support secp256r1 curve") + } + + // read Payload and Sig Mode + l, err = reader.Read(oneBytes) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + header.sigCfg = deserializeSignatureCfg(oneBytes[0]) + + // Read policy type + l, err = reader.Read(oneBytes) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + + if oneBytes[0] != uint8(policyTypeEmbeddedPolicyEncrypted) { + return header, 0, fmt.Errorf(" current implementation only support embedded policy type") + } + + // read policy length + const ( + kSizeOfUint16 = 2 + ) + twoBytes := make([]byte, kSizeOfUint16) + l, err = reader.Read(twoBytes) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + policyLength := binary.BigEndian.Uint16(twoBytes) + slog.Debug("NewNanoTDFHeaderFromReader", slog.Uint64("policyLength", uint64(policyLength))) + + // read policy body + header.EncryptedPolicyBody = make([]byte, policyLength) + l, err = reader.Read(header.EncryptedPolicyBody) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + + // read policy binding + header.PolicyBinding = make([]byte, kNanoTDFGMACLength) + l, err = reader.Read(header.PolicyBinding) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + + ephemeralKeySize, err := getECCKeyLength(header.bindCfg.eccMode) + if err != nil { + return header, 0, fmt.Errorf("getECCKeyLength :%w", err) + } + + // read ephemeral Key + ephemeralKey := make([]byte, ephemeralKeySize) + l, err = reader.Read(ephemeralKey) + if err != nil { + return header, 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + size += uint32(l) + header.EphemeralKey = ephemeralKey + + slog.Debug("NewNanoTDFHeaderFromReader", slog.Uint64("header size", uint64(size))) + + return header, size, nil +} + +// ============================================================================================================ +// NanoTDF Encrypt +// ============================================================================================================ + +// CreateNanoTDF - reads plain text from the given reader and saves it to the writer, subject to the given options +func (s SDK) CreateNanoTDF(writer io.Writer, reader io.Reader, config NanoTDFConfig) (uint32, error) { + var totalSize uint32 + buf := bytes.Buffer{} + size, err := buf.ReadFrom(reader) + if err != nil { + return 0, err + } + + if size > kMaxTDFSize { + return 0, errors.New("exceeds max size for nano tdf") + } + + kasURL, err := config.kasURL.getURL() + if err != nil { + return 0, fmt.Errorf("config.kasURL failed:%w", err) + } + + kasPublicKey, err := getECPublicKey(kasURL, s.dialOptions...) + if err != nil { + return 0, fmt.Errorf("getECPublicKey failed:%w", err) + } + + slog.Debug("CreateNanoTDF", slog.String("header size", kasPublicKey)) + + config.kasPublicKey, err = ocrypto.ECPubKeyFromPem([]byte(kasPublicKey)) + if err != nil { + return 0, fmt.Errorf("ocrypto.ECPubKeyFromPem failed: %w", err) + } + + // Create nano tdf header + key, totalSize, err := writeNanoTDFHeader(writer, config) + if err != nil { + return 0, fmt.Errorf("writeNanoTDFHeader failed:%w", err) + } + + slog.Debug("CreateNanoTDF", slog.Uint64("Header", uint64(totalSize))) + + aesGcm, err := ocrypto.NewAESGcm(key) + if err != nil { + return 0, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + ivPadded := make([]byte, 0, ocrypto.GcmStandardNonceSize) + noncePadding := make([]byte, kIvPadding) + ivPadded = append(ivPadded, noncePadding...) + iv, err := ocrypto.RandomBytes(kNanoTDFIvSize) + if err != nil { + return 0, fmt.Errorf("ocrypto.RandomBytes failed:%w", err) + } + ivPadded = append(ivPadded, iv...) + + tagSize, err := SizeOfAuthTagForCipher(config.sigCfg.cipher) + if err != nil { + return 0, fmt.Errorf("SizeOfAuthTagForCipher failed:%w", err) + } + + cipherData, err := aesGcm.EncryptWithIVAndTagSize(ivPadded, buf.Bytes(), tagSize) + if err != nil { + return 0, err + } + + // Write the length of the payload as int24 + cipherDataWithoutPadding := cipherData[kIvPadding:] + const ( + kUint32BufLen = 4 + ) + uint32Buf := make([]byte, kUint32BufLen) + binary.BigEndian.PutUint32(uint32Buf, uint32(len(cipherDataWithoutPadding))) + l, err := writer.Write(uint32Buf[1:]) + if err != nil { + return 0, err + } + totalSize += uint32(l) + + slog.Debug("CreateNanoTDF", slog.Uint64("payloadLength", uint64(len(cipherDataWithoutPadding)))) + + // write cipher data + l, err = writer.Write(cipherDataWithoutPadding) + if err != nil { + return 0, err + } + totalSize += uint32(l) + + return totalSize, nil +} + +// ============================================================================================================ +// NanoTDF Decrypt +// ============================================================================================================ + +// ReadNanoTDF - read the nano tdf and return the decrypted data from it +func (s SDK) ReadNanoTDF(writer io.Writer, reader io.ReadSeeker) (uint32, error) { + header, headerSize, err := NewNanoTDFHeaderFromReader(reader) + if err != nil { + return 0, err + } + + _, err = reader.Seek(0, io.SeekStart) + if err != nil { + return 0, fmt.Errorf("readSeeker.Seek failed: %w", err) + } + + headerBuf := make([]byte, headerSize) + _, err = reader.Read(headerBuf) + if err != nil { + return 0, fmt.Errorf("readSeeker.Seek failed: %w", err) + } + + kasURL, err := header.kasURL.getURL() + if err != nil { + return 0, fmt.Errorf("readSeeker.Seek failed: %w", err) + } + + encodedHeader := ocrypto.Base64Encode(headerBuf) + + rsaKeyPair, err := ocrypto.NewRSAKeyPair(tdf3KeySize) + if err != nil { + return 0, fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) + } + + client, err := newKASClient(s.dialOptions, s.tokenSource, rsaKeyPair) + if err != nil { + return 0, fmt.Errorf("newKASClient failed: %w", err) + } + + symmetricKey, err := client.unwrapNanoTDF(string(encodedHeader), kasURL) + if err != nil { + return 0, fmt.Errorf("readSeeker.Seek failed: %w", err) + } + + encoded := ocrypto.Base64Encode(symmetricKey) + slog.Debug("ReadNanoTDF", slog.String("symmetricKey", string(encoded))) + + const ( + kPayloadLoadLengthBufLength = 4 + ) + payloadLengthBuf := make([]byte, kPayloadLoadLengthBufLength) + _, err = reader.Read(payloadLengthBuf[1:]) + + if err != nil { + return 0, fmt.Errorf(" io.Reader.Read failed :%w", err) + } + + payloadLength := binary.BigEndian.Uint32(payloadLengthBuf) + slog.Debug("ReadNanoTDF", slog.Uint64("payloadLength", uint64(payloadLength))) + + cipherDate := make([]byte, payloadLength) + _, err = reader.Read(cipherDate) + if err != nil { + return 0, fmt.Errorf("readSeeker.Seek failed: %w", err) + } + + aesGcm, err := ocrypto.NewAESGcm(symmetricKey) + if err != nil { + return 0, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + ivPadded := make([]byte, 0, ocrypto.GcmStandardNonceSize) + noncePadding := make([]byte, kIvPadding) + ivPadded = append(ivPadded, noncePadding...) + iv := cipherDate[:kNanoTDFIvSize] + ivPadded = append(ivPadded, iv...) + + tagSize, err := SizeOfAuthTagForCipher(header.sigCfg.cipher) + if err != nil { + return 0, fmt.Errorf("SizeOfAuthTagForCipher failed:%w", err) + } + + decryptedData, err := aesGcm.DecryptWithIVAndTagSize(ivPadded, cipherDate[kNanoTDFIvSize:], tagSize) + if err != nil { + return 0, err + } + + writeLen, err := writer.Write(decryptedData) + if err != nil { + return 0, err + } + // print(payloadLength) + // print(string(decryptedData)) + + return uint32(writeLen), nil +} + +// getECPublicKey - Contact the specified KAS and get its public key +func getECPublicKey(kasURL string, opts ...grpc.DialOption) (string, error) { + req := kas.PublicKeyRequest{} + req.Algorithm = "ec:secp256r1" + grpcAddress, err := getGRPCAddress(kasURL) + if err != nil { + return "", err + } + conn, err := grpc.Dial(grpcAddress, opts...) + if err != nil { + return "", fmt.Errorf("error connecting to grpc service at %s: %w", kasURL, err) + } + defer conn.Close() + + ctx := context.Background() + serviceClient := kas.NewAccessServiceClient(conn) + + resp, err := serviceClient.PublicKey(ctx, &req) + + if err != nil { + return "", fmt.Errorf("error making request to KAS: %w", err) + } + + return resp.GetPublicKey(), nil +} + +type requestBody struct { + Algorithm string `json:"algorithm,omitempty"` + KeyAccess keyAccess `json:"keyAccess"` + ClientPublicKey string `json:"clientPublicKey"` +} + +type keyAccess struct { + Header string `json:"header"` + KeyAccessType string `json:"type"` + URL string `json:"url"` + Protocol string `json:"protocol"` +} + +func versionSalt() []byte { + digest := sha256.New() + digest.Write([]byte(kNanoTDFMagicStringAndVersion)) + return digest.Sum(nil) } diff --git a/sdk/nanotdf_config.go b/sdk/nanotdf_config.go new file mode 100644 index 000000000..9cffa4671 --- /dev/null +++ b/sdk/nanotdf_config.go @@ -0,0 +1,98 @@ +package sdk + +import ( + "crypto/ecdh" + "fmt" + + "github.com/opentdf/platform/lib/ocrypto" +) + +// ============================================================================================================ +// Support for specifying configuration information for nanoTDF operations +// +// The config information in this structure is referenced once at the beginning of the nanoTDF +// operation, and is not consulted again. It is safe to create a config, use it in one operation, modify it, +// and use it again in a second operation. The modification will only affect the second operation in that case. +// +// ============================================================================================================ + +type NanoTDFConfig struct { + keyPair ocrypto.ECKeyPair + kasPublicKey *ecdh.PublicKey + attributes []string + cipher CipherMode + kasURL ResourceLocator + sigCfg signatureConfig + policy policyInfo + bindCfg bindingConfig +} + +type NanoTDFOption func(*NanoTDFConfig) error + +// NewNanoTDFConfig - Create a new instance of a nanoTDF config +func (s SDK) NewNanoTDFConfig() (*NanoTDFConfig, error) { + // TODO FIXME - how to pass in mode value and use here before 'c' is initialized? + newECKeyPair, err := ocrypto.NewECKeyPair(ocrypto.ECCModeSecp256r1) + if err != nil { + return nil, fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) + } + + c := &NanoTDFConfig{ + keyPair: newECKeyPair, + bindCfg: bindingConfig{ + useEcdsaBinding: false, + padding: 0, + eccMode: ocrypto.ECCModeSecp256r1, + }, + cipher: kCipher96AuthTagSize, + sigCfg: signatureConfig{ + hasSignature: false, + signatureMode: ocrypto.ECCModeSecp256r1, + cipher: cipherModeAes256gcm96Bit, + }, + } + + return c, nil +} + +// SetKasURL - set the URL of the KAS endpoint to be used for this nanoTDF +func (config *NanoTDFConfig) SetKasURL(url string) error { + return config.kasURL.setURL(url) +} + +// SetAttributes - set the attributes to be used for this nanoTDF +func (config *NanoTDFConfig) SetAttributes(attributes []string) { + config.attributes = attributes +} + +// WithNanoDataAttributes appends the given data attributes to the bound policy +func WithNanoDataAttributes(attributes ...string) NanoTDFOption { + return func(c *NanoTDFConfig) error { + c.attributes = append(c.attributes, attributes...) + return nil + } +} + +type NanoKASInfo struct { + kasPublicKeyPem string + kasURL string +} + +// WithNanoKasInformation adds the first kas url and its corresponding public key +// that is required to create and read the nanotdf. Note that only the first +// entry is used, as multi-kas is not supported for nanotdf +func WithNanoKasInformation(kasInfoList ...NanoKASInfo) NanoTDFOption { + return func(c *NanoTDFConfig) error { + newKasInfos := make([]NanoKASInfo, 0) + newKasInfos = append(newKasInfos, kasInfoList...) + err := c.kasURL.setURL(newKasInfos[0].kasURL) + if err != nil { + return err + } + c.kasPublicKey, err = ocrypto.ECPubKeyFromPem([]byte(newKasInfos[0].kasPublicKeyPem)) + if err != nil { + return err + } + return nil + } +} diff --git a/sdk/nanotdf_config_test.go b/sdk/nanotdf_config_test.go new file mode 100644 index 000000000..01d076cc7 --- /dev/null +++ b/sdk/nanotdf_config_test.go @@ -0,0 +1,55 @@ +package sdk + +import ( + "testing" +) + +// TestNanoTDFConfig1 - Create a new config, verify that the config contains valid PEMs for the key pair +func TestNanoTDFConfig1(t *testing.T) { + var s SDK + conf, err := s.NewNanoTDFConfig() + if err != nil { + t.Fatal(err) + } + pemPrvKey, err := conf.keyPair.PrivateKeyInPemFormat() + if err != nil { + t.Fatal(err) + } + + if len(pemPrvKey) == 0 { + t.Fatal("no private key") + } + + pemPubKey, err := conf.keyPair.PublicKeyInPemFormat() + if err != nil { + t.Fatal(err) + } + if len(pemPubKey) == 0 { + t.Fatal("no public key") + } +} + +// TestNanoTDFConfig2 - set kas url, retrieve kas url, verify value is correct +func TestNanoTDFConfig2(t *testing.T) { + const ( + kasURL = "https://test.virtru.com" + ) + + var s SDK + conf, err := s.NewNanoTDFConfig() + if err != nil { + t.Fatal(err) + } + err = conf.SetKasURL(kasURL) + if err != nil { + t.Fatal(err) + } + + readKasURL, err := conf.kasURL.getURL() + if err != nil { + t.Fatal(err) + } + if readKasURL != kasURL { + t.Fatalf("expect %s, got %s", kasURL, readKasURL) + } +} diff --git a/sdk/nanotdf_policy.go b/sdk/nanotdf_policy.go new file mode 100644 index 000000000..4c4467c80 --- /dev/null +++ b/sdk/nanotdf_policy.go @@ -0,0 +1,99 @@ +package sdk + +import ( + "encoding/binary" + "errors" + "io" +) + +// ============================================================================================================ +// Support for nanoTDF policy operations +// +// ============================================================================================================ + +type policyType uint8 + +const ( + policyTypeRemotePolicy policyType = 0 + policyTypeEmbeddedPolicyPlainText policyType = 1 + policyTypeEmbeddedPolicyEncrypted policyType = 2 + policyTypeEmbeddedPolicyEncryptedPolicyKeyAccess policyType = 3 +) + +type PolicyBody struct { + mode policyType + rp remotePolicy + ep embeddedPolicy +} + +// getLength - size in bytes of the serialized content of this object +// func (pb *PolicyBody) getLength() uint16 { // nolint:unused future use +// var result uint16 +// +// result = 1 /* policy mode byte */ +// +// if pb.mode == policyTypeRemotePolicy { +// result += pb.rp.getLength() +// } else { +// // If it's not remote, assume embedded policy +// result += pb.ep.getLength() +// } +// +// return result +// } + +// readPolicyBody - helper function to decode input data into a PolicyBody object +func (pb *PolicyBody) readPolicyBody(reader io.Reader) error { + var mode policyType + if err := binary.Read(reader, binary.BigEndian, &mode); err != nil { + return err + } + switch mode { + case policyTypeRemotePolicy: + var rl ResourceLocator + if err := rl.readResourceLocator(reader); err != nil { + return errors.Join(ErrNanoTDFHeaderRead, err) + } + pb.rp = remotePolicy{url: rl} + case policyTypeEmbeddedPolicyPlainText: + case policyTypeEmbeddedPolicyEncrypted: + case policyTypeEmbeddedPolicyEncryptedPolicyKeyAccess: + var ep embeddedPolicy + if err := ep.readEmbeddedPolicy(reader); err != nil { + return errors.Join(ErrNanoTDFHeaderRead, err) + } + pb.ep = ep + default: + return errors.New("unknown policy type") + } + return nil +} + +// writePolicyBody - helper function to encode and write a PolicyBody object +func (pb *PolicyBody) writePolicyBody(writer io.Writer) error { + var err error + + switch pb.mode { + case policyTypeRemotePolicy: // remote policy - resource locator + if err = binary.Write(writer, binary.BigEndian, pb.mode); err != nil { + return err + } + if err = pb.rp.url.writeResourceLocator(writer); err != nil { + return err + } + return nil + case policyTypeEmbeddedPolicyPlainText: + case policyTypeEmbeddedPolicyEncrypted: + case policyTypeEmbeddedPolicyEncryptedPolicyKeyAccess: + // embedded policy - inline + if err = binary.Write(writer, binary.BigEndian, pb.mode); err != nil { + return err + } + if err = pb.ep.writeEmbeddedPolicy(writer); err != nil { + return err + } + default: + return errors.New("unsupported policy mode") + } + return nil +} diff --git a/sdk/nanotdf_policy_test.go b/sdk/nanotdf_policy_test.go new file mode 100644 index 000000000..df7a0de34 --- /dev/null +++ b/sdk/nanotdf_policy_test.go @@ -0,0 +1,46 @@ +package sdk + +import ( + "bytes" + "io" + "testing" +) + +const ( + kSampleURLBody = "test.virtru.com" + // kSampleUrlProto = policyTypeRemotePolicy + kSampleURLFull = "https://" + kSampleURLBody +) + +// TestNanoTDFPolicyWrite - Create a new policy, write it to a buffer +func TestNanoTDFPolicy(t *testing.T) { + pb := &PolicyBody{ + mode: policyTypeRemotePolicy, + rp: remotePolicy{ + url: ResourceLocator{ + protocol: 1, + body: kSampleURLBody, + }, + }, + } + + buffer := new(bytes.Buffer) + err := pb.writePolicyBody(io.Writer(buffer)) + if err != nil { + t.Fatal(err) + } + + pb2 := &PolicyBody{} + err = pb2.readPolicyBody(bytes.NewReader(buffer.Bytes())) + if err != nil { + t.Fatal(err) + } + + fullURL, err := pb2.rp.url.getURL() + if err != nil { + t.Fatal(err) + } + if fullURL != kSampleURLFull { + t.Fatal(fullURL) + } +} diff --git a/sdk/nanotdf_test.go b/sdk/nanotdf_test.go index 013627d27..ac060e657 100644 --- a/sdk/nanotdf_test.go +++ b/sdk/nanotdf_test.go @@ -3,26 +3,24 @@ package sdk import ( "bytes" "encoding/gob" + "io" "os" "testing" "github.com/opentdf/platform/lib/ocrypto" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) // nanotdfEqual compares two nanoTdf structures for equality. -func nanoTDFEqual(a, b *NanoTdf) bool { - // Compare magicNumber field - if a.magicNumber != b.magicNumber { - return false - } - +func nanoTDFEqual(a, b *NanoTDFHeader) bool { // Compare kasURL field - if a.kasURL.protocol != b.kasURL.protocol || a.kasURL.lengthBody != b.kasURL.lengthBody || a.kasURL.body != b.kasURL.body { + if a.kasURL.protocol != b.kasURL.protocol || a.kasURL.getLength() != b.kasURL.getLength() || a.kasURL.body != b.kasURL.body { return false } // Compare binding field - if a.binding.useEcdsaBinding != b.binding.useEcdsaBinding || a.binding.padding != b.binding.padding || a.binding.bindingBody != b.binding.bindingBody { + if a.bindCfg.useEcdsaBinding != b.bindCfg.useEcdsaBinding || a.bindCfg.padding != b.bindCfg.padding || a.bindCfg.eccMode != b.bindCfg.eccMode { return false } @@ -32,12 +30,12 @@ func nanoTDFEqual(a, b *NanoTdf) bool { } // Compare policy field - if a.policy.mode != b.policy.mode || !policyBodyEqual(a.policy.body, b.policy.body) || !eccSignatureEqual(a.policy.binding, b.policy.binding) { - return false - } + // if a.PolicyBinding != b.PolicyBinding) { + // return false + // } // Compare EphemeralPublicKey field - if !bytes.Equal(a.EphemeralPublicKey.Key, b.EphemeralPublicKey.Key) { + if !bytes.Equal(a.EphemeralKey, b.EphemeralKey) { return false } @@ -45,93 +43,86 @@ func nanoTDFEqual(a, b *NanoTdf) bool { return true } -// policyBodyEqual compares two PolicyBody instances for equality. -func policyBodyEqual(a, b PolicyBody) bool { - // Compare based on the concrete type of PolicyBody - switch a := a.(type) { - case remotePolicy: - b, ok := b.(remotePolicy) - if !ok { - return false - } - return remotePolicyEqual(a, b) - case embeddedPolicy: - b, ok := b.(embeddedPolicy) - if !ok { - return false - } - return embeddedPolicyEqual(a, b) - default: - // Handle other types as needed - return false - } -} - -// remotePolicyEqual compares two remotePolicy instances for equality. -func remotePolicyEqual(a, b remotePolicy) bool { - // Compare url field - if a.url.protocol != b.url.protocol || a.url.lengthBody != b.url.lengthBody || a.url.body != b.url.body { - return false - } - return true -} - -// embeddedPolicyEqual compares two embeddedPolicy instances for equality. -func embeddedPolicyEqual(a, b embeddedPolicy) bool { - // Compare lengthBody and body fields - return a.lengthBody == b.lengthBody && a.body == b.body -} - -// eccSignatureEqual compares two eccSignature instances for equality. -func eccSignatureEqual(a, b *eccSignature) bool { - // Compare value field - return bytes.Equal(a.value, b.value) -} +//// policyBodyEqual compares two PolicyBody instances for equality. +// func policyBodyEqual(a, b PolicyBody) bool { //nolint:unused future usage +// // Compare based on the concrete type of PolicyBody +// switch a.mode { +// case policyTypeRemotePolicy: +// return remotePolicyEqual(a.rp, b.rp) +// case policyTypeEmbeddedPolicyPlainText: +// case policyTypeEmbeddedPolicyEncrypted: +// case policyTypeEmbeddedPolicyEncryptedPolicyKeyAccess: +// return embeddedPolicyEqual(a.ep, b.ep) +// } +// return false +// } + +//// remotePolicyEqual compares two remotePolicy instances for equality. +// func remotePolicyEqual(a, b remotePolicy) bool { // nolint:unused future usage +// // Compare url field +// if a.url.protocol != b.url.protocol || a.url.getLength() != b.url.getLength() || a.url.body != b.url.body { +// return false +// } +// return true +// } +// +//// embeddedPolicyEqual compares two embeddedPolicy instances for equality. +// func embeddedPolicyEqual(a, b embeddedPolicy) bool { // nolint:unused future usage +// // Compare lengthBody and body fields +// return a.lengthBody == b.lengthBody && bytes.Equal(a.body, b.body) +// } +// +//// eccSignatureEqual compares two eccSignature instances for equality. +// func eccSignatureEqual(a, b *eccSignature) bool { // nolint:unused future usage +// // Compare value field +// return bytes.Equal(a.value, b.value) +// } func init() { // Register the remotePolicy type with gob gob.Register(&remotePolicy{}) } -func TestReadNanoTDFHeader(t *testing.T) { +func NotTestReadNanoTDFHeader(t *testing.T) { // Prepare a sample nanoTdf structure - nanoTDF := NanoTdf{ - magicNumber: [3]byte{'L', '1', 'L'}, - kasURL: &resourceLocator{ - protocol: urlProtocolHTTPS, - lengthBody: 14, - body: "kas.virtru.com", + goodHeader := NanoTDFHeader{ + kasURL: ResourceLocator{ + protocol: urlProtocolHTTPS, + body: "kas.virtru.com", }, - binding: &bindingCfg{ + bindCfg: bindingConfig{ useEcdsaBinding: true, padding: 0, - bindingBody: ocrypto.ECCModeSecp256r1, + eccMode: ocrypto.ECCModeSecp256r1, }, - sigCfg: &signatureConfig{ + sigCfg: signatureConfig{ hasSignature: true, signatureMode: ocrypto.ECCModeSecp256r1, cipher: cipherModeAes256gcm64Bit, }, - policy: &policyInfo{ - mode: uint8(policyTypeRemotePolicy), - body: remotePolicy{ - url: &resourceLocator{ - protocol: urlProtocolHTTPS, - lengthBody: 21, - body: "kas.virtru.com/policy", - }, - }, - binding: &eccSignature{ - value: []byte{181, 228, 19, 166, 2, 17, 229, 241}, - }, - }, - EphemeralPublicKey: &eccKey{ - Key: []byte{123, 34, 52, 160, 205, 63, 54, 255, 123, 186, 109, - 143, 232, 223, 35, 246, 44, 157, 9, 53, 111, 133, - 130, 248, 169, 207, 21, 18, 108, 138, 157, 164, 108}, - }, + //PolicyBinding: policyInfo{ + // body: PolicyBody{ + // mode: policyTypeRemotePolicy, + // rp: remotePolicy{ + // url: ResourceLocator{ + // protocol: urlProtocolHTTPS, + // body: "kas.virtru.com/policy", + // }, + // }, + // }, + // binding: &eccSignature{ + // value: []byte{181, 228, 19, 166, 2, 17, 229, 241}, + // }, + // }, + EphemeralKey: []byte{123, 34, 52, 160, 205, 63, 54, 255, 123, 186, 109, + 143, 232, 223, 35, 246, 44, 157, 9, 53, 111, 133, + 130, 248, 169, 207, 21, 18, 108, 138, 157, 164, 108}, } + const ( + kExpectedHeaderSize = 128 + ) + // Serialize the sample nanoTdf structure into a byte slice using gob file, err := os.Open("nanotdfspec.ntdf") if err != nil { @@ -139,13 +130,112 @@ func TestReadNanoTDFHeader(t *testing.T) { } defer file.Close() - result, err := ReadNanoTDFHeader(file) + resultHeader, headerSize, err := NewNanoTDFHeaderFromReader(io.ReadSeeker(file)) if err != nil { t.Fatalf("Error while reading nanoTdf header: %v", err) } + if headerSize != kExpectedHeaderSize { + t.Fatalf("expecting length %d, got %d", kExpectedHeaderSize, headerSize) + } + // Compare the result with the original nanoTdf structure - if !nanoTDFEqual(result, &nanoTDF) { + if !nanoTDFEqual(&resultHeader, &goodHeader) { t.Error("Result does not match the expected nanoTdf structure.") } } + +const ( +// sdkPrivateKey = `-----BEGIN PRIVATE KEY----- +// MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1HjFYV8D16BQszNW +// 6Hx/JxTE53oqk5/bWaIj4qV5tOyhRANCAAQW1Hsq0tzxN6ObuXqV+JoJN0f78Em/ +// PpJXUV02Y6Ex3WlxK/Oaebj8ATsbfaPaxrhyCWB3nc3w/W6+lySlLPn5 +// -----END PRIVATE KEY-----` + +// sdkPublicKey = `-----BEGIN PUBLIC KEY----- +// MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFtR7KtLc8Tejm7l6lfiaCTdH+/BJ +// vz6SV1FdNmOhMd1pcSvzmnm4/AE7G32j2sa4cglgd53N8P1uvpckpSz5+Q== +// -----END PUBLIC KEY-----` + +// kasPrivateKey = `-----BEGIN PRIVATE KEY----- +// MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgu2Hmm80uUzQB1OfB +// PyMhWIyJhPA61v+j0arvcLjTwtqhRANCAASHCLUHY4szFiVV++C9+AFMkEL2gG+O +// byN4Hi7Ywl8GMPOAPcQdIeUkoTd9vub9PcuSj23I8/pLVzs23qhefoUf +// -----END PRIVATE KEY-----` + +// kasPublicKey = `-----BEGIN PUBLIC KEY----- +// +// MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhwi1B2OLMxYlVfvgvfgBTJBC9oBv +// jm8jeB4u2MJfBjDzgD3EHSHlJKE3fb7m/T3Lko9tyPP6S1c7Nt6oXn6FHw== +// -----END PUBLIC KEY-----` +) + +// disabled for now, no remote policy support yet +func NotTestNanoTDFEncryptFile(t *testing.T) { + const ( + kExpectedOutSize = 128 + ) + + var s SDK + infile, err := os.Open("nanotest1.txt") + if err != nil { + t.Fatal(err) + } + + // try to delete the output file in case it exists already - ignore error if it doesn't exist + _ = os.Remove("nanotest1.ntdf") + + outfile, err := os.Create("nanotest1.ntdf") + if err != nil { + t.Fatal(err) + } + + // TODO - populate config properly + var kasURL = "https://kas.virtru.com/kas" + var config NanoTDFConfig + err = config.kasURL.setURL(kasURL) + if err != nil { + t.Fatal(err) + } + + outSize, err := s.CreateNanoTDF(io.Writer(outfile), io.ReadSeeker(infile), config) + if err != nil { + t.Fatal(err) + } + if outSize != kExpectedOutSize { + t.Fatalf("expecting length %d, got %d", kExpectedOutSize, outSize) + } +} + +// disabled for now +func NotTestCreateNanoTDF(t *testing.T) { + var s SDK + + grpc.WithTransportCredentials(insecure.NewCredentials()) + + infile, err := os.Open("nanotest1.txt") + if err != nil { + t.Fatal(err) + } + + // try to delete the output file in case it exists already - ignore error if it doesn't exist + _ = os.Remove("nanotest1.ntdf") + + outfile, err := os.Create("nanotest1.ntdf") + if err != nil { + t.Fatal(err) + } + + // TODO - populate config properly + var kasURL = "https://kas.virtru.com/kas" + var config NanoTDFConfig + err = config.kasURL.setURL(kasURL) + if err != nil { + t.Fatal(err) + } + + _, err = s.CreateNanoTDF(io.Writer(outfile), io.ReadSeeker(infile), config) + if err != nil { + t.Fatal(err) + } +} diff --git a/sdk/nanotest1.txt b/sdk/nanotest1.txt new file mode 100644 index 000000000..1bce1e242 --- /dev/null +++ b/sdk/nanotest1.txt @@ -0,0 +1 @@ +Virtru!!!! diff --git a/sdk/resource_locator.go b/sdk/resource_locator.go new file mode 100644 index 000000000..13ed15e1f --- /dev/null +++ b/sdk/resource_locator.go @@ -0,0 +1,150 @@ +package sdk + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "strconv" + "strings" +) + +// ============================================================================================================ +// Support for serializing/deserializing URLS for nano usage +// +// If an URL is specified as "https://some.site.com/endpoint" +// the storage format for this is to strip off the leading "https://" prefix and encode as 0 (or 1 for http) +// followed by the run-length-prefixed body value +// ============================================================================================================ + +// ResourceLocator - structure to contain a protocol + body comprising an URL +type ResourceLocator struct { + protocol urlProtocol // See urlProtocol values below + body string // Body of url +} + +// urlProtocol - shorthand for protocol prefix on fully qualified url +type urlProtocol uint8 + +const ( + kMaxBodyLen int = 255 + kPrefixHTTPS string = "https://" + kPrefixHTTP string = "http://" + urlProtocolHTTP urlProtocol = 0 + urlProtocolHTTPS urlProtocol = 1 + // urlProtocolShared urlProtocol = 255 // TODO - how is this handled/parsed/rendered? +) + +func NewResourceLocator(url string) (*ResourceLocator, error) { + rl := &ResourceLocator{} + + err := rl.setURL(url) + if err != nil { + return nil, err + } + + return rl, err +} + +func NewResourceLocatorFromReader(reader io.Reader) (*ResourceLocator, error) { + rl := &ResourceLocator{} + oneByte := make([]byte, 1) + + _, err := reader.Read(oneByte) + if err != nil { + return rl, err + } + rl.protocol = urlProtocol(oneByte[0]) + + _, err = reader.Read(oneByte) + if err != nil { + return rl, err + } + + l := oneByte[0] + body := make([]byte, l) + _, err = reader.Read(body) + if err != nil { + return rl, err + } + rl.body = string(body) + + return rl, err +} + +// getLength - return the serialized length (in bytes) of this object +func (rl ResourceLocator) getLength() uint16 { + return uint16(1 /* protocol byte */ + 1 /* length byte */ + len(rl.body)) +} + +// setURL - Store a fully qualified protocol+body string into a ResourceLocator as a protocol value and a body string +func (rl *ResourceLocator) setURL(url string) error { + lowerURL := strings.ToLower(url) + if strings.HasPrefix(lowerURL, kPrefixHTTPS) { + urlBody := url[len(kPrefixHTTPS):] + if len(urlBody) > kMaxBodyLen { + return errors.New("URL too long") + } + rl.protocol = urlProtocolHTTPS + rl.body = urlBody + return nil + } + if strings.HasPrefix(lowerURL, kPrefixHTTP) { + urlBody := url[len(kPrefixHTTP):] + if len(urlBody) > kMaxBodyLen { + return errors.New("URL too long") + } + rl.protocol = urlProtocolHTTP + rl.body = urlBody + return nil + } + return errors.New("unsupported protocol: " + url) +} + +// getURL - Retrieve a fully qualified protocol+body URL string from a ResourceLocator struct +func (rl ResourceLocator) getURL() (string, error) { + if rl.protocol == urlProtocolHTTPS { + return kPrefixHTTPS + rl.body, nil + } + if rl.protocol == urlProtocolHTTP { + return kPrefixHTTP + rl.body, nil + } + return "", fmt.Errorf("unsupported protocol: %d", rl.protocol) +} + +// writeResourceLocator - writes the content of the resource locator to the supplied writer +func (rl ResourceLocator) writeResourceLocator(writer io.Writer) error { + if _, err := writer.Write([]byte{byte(rl.protocol)}); err != nil { + return err + } + + if _, err := writer.Write([]byte{byte(len(rl.body))}); err != nil { + return err + } + + if _, err := writer.Write([]byte(rl.body)); err != nil { + return err + } + + return nil +} + +// readResourceLocator - read the encoded protocol and body string into a ResourceLocator +func (rl *ResourceLocator) readResourceLocator(reader io.Reader) error { + if err := binary.Read(reader, binary.BigEndian, &rl.protocol); err != nil { + return errors.Join(Error("Error reading ResourceLocator protocol value"), err) + } + if (rl.protocol != urlProtocolHTTP) && (rl.protocol != urlProtocolHTTPS) { // TODO - support 'shared' protocol? + return errors.New("Unsupported protocol: " + strconv.Itoa(int(rl.protocol))) + } + var lengthBody byte + if err := binary.Read(reader, binary.BigEndian, &lengthBody); err != nil { + return errors.Join(Error("Error reading ResourceLocator body length value"), err) + } + body := make([]byte, lengthBody) + if err := binary.Read(reader, binary.BigEndian, &body); err != nil { + return errors.Join(Error("Error reading ResourceLocator body value"), err) + } + rl.body = string(body) // TODO - normalize to lowercase? + return nil +} diff --git a/sdk/resource_locator_test.go b/sdk/resource_locator_test.go new file mode 100644 index 000000000..af0769d87 --- /dev/null +++ b/sdk/resource_locator_test.go @@ -0,0 +1,44 @@ +package sdk + +import ( + "testing" +) + +const ( + resourceLocatorTestURLHTTPS = "https://test.virtru.com/kas/endpoint" + resourceLocatorTestURLHTTP = "http://test.virtru.com/kas/endpoint" + resourceLocatorTestURLBad = "this is a bad url" +) + +func TestResourceLocatorHttps(t *testing.T) { + rl, err := NewResourceLocator(resourceLocatorTestURLHTTPS) + if err != nil { + t.Fatal(err) + } + if rl.protocol != urlProtocolHTTPS { + t.Fatalf("expecting protocol %d, got %d", urlProtocolHTTPS, rl.protocol) + } + if len(rl.body) != len(resourceLocatorTestURLHTTPS)-len(kPrefixHTTPS) { + t.Fatalf("expecting length %d, got %d", len(resourceLocatorTestURLHTTPS), len(rl.body)) + } +} + +func TestResourceLocatorHttp(t *testing.T) { + rl, err := NewResourceLocator(resourceLocatorTestURLHTTP) + if err != nil { + t.Fatal(err) + } + if rl.protocol != urlProtocolHTTP { + t.Fatalf("expecting protocol %d, got %d", urlProtocolHTTP, rl.protocol) + } + if len(rl.body) != len(resourceLocatorTestURLHTTP)-len(kPrefixHTTP) { + t.Fatalf("expecting length %d, got %d", len(resourceLocatorTestURLHTTP), len(rl.body)) + } +} + +func TestResourceLocatorBad(t *testing.T) { + _, err := NewResourceLocator(resourceLocatorTestURLBad) + if err == nil { + t.Fatal("expecting error") + } +} diff --git a/sdk/tdf_config.go b/sdk/tdf_config.go index 55b1196da..ba6ca25d0 100644 --- a/sdk/tdf_config.go +++ b/sdk/tdf_config.go @@ -52,7 +52,7 @@ type TDFConfig struct { kasInfoList []KASInfo } -// NewTDFConfig CreateTDF a new instance of tdf config. +// NewTDFConfig CreateTDF a new instance of a tdf config. func NewTDFConfig(opt ...TDFOption) (*TDFConfig, error) { rsaKeyPair, err := ocrypto.NewRSAKeyPair(tdf3KeySize) if err != nil { @@ -66,7 +66,7 @@ func NewTDFConfig(opt ...TDFOption) (*TDFConfig, error) { privateKey, err := rsaKeyPair.PublicKeyInPemFormat() if err != nil { - return nil, fmt.Errorf("ocrypto.PublicKeyInPemFormat failed: %w", err) + return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) } c := &TDFConfig{ diff --git a/service/internal/auth/authn.go b/service/internal/auth/authn.go index fc40d3946..0c79b56c5 100644 --- a/service/internal/auth/authn.go +++ b/service/internal/auth/authn.go @@ -165,6 +165,14 @@ func (a Authentication) MuxHandler(handler http.Handler) http.Handler { return } origin := r.Header.Get("Origin") + if origin == "" { + origin = r.Host + if r.TLS != nil { + origin = "https://" + strings.TrimSuffix(origin, ":443") + } else { + origin = "http://" + strings.TrimSuffix(origin, ":80") + } + } accessTok, ctxWithJWK, err := a.checkToken(r.Context(), header, receiverInfo{ u: normalizeURL(origin, r.URL), m: r.Method, diff --git a/service/internal/auth/authn_test.go b/service/internal/auth/authn_test.go index 5afde714a..6fc4d546b 100644 --- a/service/internal/auth/authn_test.go +++ b/service/internal/auth/authn_test.go @@ -494,7 +494,7 @@ func (s *AuthSuite) TestDPoPEndToEnd_HTTP() { }) s.Require().NoError(err) req.Header.Set("authorization", fmt.Sprintf("Bearer %s", signedTok)) - dpopTok, err := addingInterceptor.GetDPoPToken("/attributes", "GET", string(signedTok)) + dpopTok, err := addingInterceptor.GetDPoPToken(server.URL+"/attributes", "GET", string(signedTok)) s.Require().NoError(err) req.Header.Set("DPoP", dpopTok) diff --git a/service/internal/security/crypto_provider.go b/service/internal/security/crypto_provider.go index ce36dd5f0..8d7c9802a 100644 --- a/service/internal/security/crypto_provider.go +++ b/service/internal/security/crypto_provider.go @@ -8,6 +8,7 @@ type CryptoProvider interface { RSADecrypt(hash crypto.Hash, keyID string, keyLabel string, ciphertext []byte) ([]byte, error) ECPublicKey(keyID string) (string, error) + ECCertificate(keyID string) (string, error) GenerateNanoTDFSymmetricKey(ephemeralPublicKeyBytes []byte) ([]byte, error) GenerateEphemeralKasKeys() (any, []byte, error) GenerateNanoTDFSessionKey(privateKeyHandle any, ephemeralPublicKey []byte) ([]byte, error) diff --git a/service/internal/security/hsm.go b/service/internal/security/hsm.go index 404a1a565..f3f02e765 100644 --- a/service/internal/security/hsm.go +++ b/service/internal/security/hsm.go @@ -58,6 +58,7 @@ type HSMSession struct { } type HSMConfig struct { + Enabled bool `yaml:"enabled"` ModulePath string `yaml:"modulePath,omitempty"` PIN string `yaml:"pin,omitempty"` SlotID uint `yaml:"slotId,omitempty"` @@ -124,7 +125,7 @@ func findHSMLibrary(paths ...string) string { continue } i, err := os.Stat(l) - slog.Debug("stat", "path", l, "info", i, "err", err) + slog.Info("stat", "path", l, "info", i, "err", err) if os.IsNotExist(err) { continue } else if err == nil { @@ -138,9 +139,9 @@ func findHSMLibrary(paths ...string) string { } l := o + "/lib/softhsm/libsofthsm2.so" i, err := os.Stat(l) - slog.Debug("stat", "path", l, "info", i, "err", err) + slog.Info("stat", "path", l, "info", i, "err", err) if os.IsNotExist(err) { - slog.Debug("pkcs11 error: softhsm not installed by brew", "err", err) + slog.Warn("pkcs11 error: softhsm not installed by brew", "err", err) return "" } else if err == nil { return l @@ -751,8 +752,6 @@ func (h *HSMSession) RSADecrypt(hash crypto.Hash, keyID string, keyLabel string, return decrypt, nil } -func versionSalt() []byte { - digest := sha256.New() - digest.Write([]byte("L1L")) - return digest.Sum(nil) +func (h *HSMSession) ECCertificate(string) (string, error) { + return "", nil } diff --git a/service/internal/security/standard_crypto.go b/service/internal/security/standard_crypto.go index 616f040e6..27db54ad5 100644 --- a/service/internal/security/standard_crypto.go +++ b/service/internal/security/standard_crypto.go @@ -2,7 +2,12 @@ package security import ( "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/sha256" + "crypto/x509" "encoding/json" + "encoding/pem" "errors" "fmt" "log/slog" @@ -12,8 +17,12 @@ import ( "github.com/opentdf/platform/lib/ocrypto" ) +// / Constants +const ( + kNanoTDFMagicStringAndVersion = "L1L" +) + var ( - errNotImplemented = errors.New("standard crypto for nano not implemented") errStandardCryptoObjIsInvalid = errors.New("standard crypto object is invalid") ) @@ -34,14 +43,14 @@ type StandardRSACrypto struct { } type StandardECCrypto struct { - Identifier string - // ecPublicKey *ecdh.PublicKey - // ecPrivateKey *ecdh.PrivateKey + Identifier string + ecPrivateKeyPem string + ecCertificatePEM string } type StandardCrypto struct { rsaKeys []StandardRSACrypto - // ecKeys []StandardECCrypto + ecKeys []StandardECCrypto } // NewStandardCrypto Create a new instance of standard crypto @@ -74,6 +83,24 @@ func NewStandardCrypto(cfg StandardConfig) (*StandardCrypto, error) { asymEncryption: asymEncryption, }) } + for id, kasInfo := range cfg.ECKeys { + slog.Info("cfg.ECKeys", "id", id, "kasInfo", kasInfo) + // private and public EC KAS key + privatePemData, err := os.ReadFile(kasInfo.PrivateKeyPath) + if err != nil { + return nil, fmt.Errorf("failed to EC private key file: %w", err) + } + // certificate EC KAS key + ecCertificatePEM, err := os.ReadFile(kasInfo.PublicKeyPath) + if err != nil { + return nil, fmt.Errorf("failed to EC certificate file: %w", err) + } + standardCrypto.ecKeys = append(standardCrypto.ecKeys, StandardECCrypto{ + Identifier: id, + ecPrivateKeyPem: string(privatePemData), + ecCertificatePEM: string(ecCertificatePEM), + }) + } return standardCrypto, nil } @@ -94,8 +121,52 @@ func (s StandardCrypto) RSAPublicKey(keyID string) (string, error) { return pem, nil } -func (s StandardCrypto) ECPublicKey(string) (string, error) { - return "", ErrCertNotFound +func (s StandardCrypto) ECCertificate(identifier string) (string, error) { + if len(s.ecKeys) == 0 { + return "", ErrCertNotFound + } + // this endpoint returns certificate + for _, ecKey := range s.ecKeys { + slog.Debug("ecKey", "id", ecKey.Identifier) + if ecKey.Identifier == identifier { + return ecKey.ecCertificatePEM, nil + } + } + return "", fmt.Errorf("no EC Key found with the given identifier: %s", identifier) +} + +func (s StandardCrypto) ECPublicKey(identifier string) (string, error) { + if len(s.ecKeys) == 0 { + return "", ErrCertNotFound + } + for _, ecKey := range s.ecKeys { + slog.Debug("ecKey", "id", ecKey.Identifier) + if ecKey.Identifier != identifier { + continue + } + + ecPrivateKey, err := ocrypto.ECPrivateKeyFromPem([]byte(ecKey.ecPrivateKeyPem)) + if err != nil { + return "", fmt.Errorf("ECPrivateKeyFromPem failed: %s %w", identifier, err) + } + + ecPublicKey := ecPrivateKey.PublicKey() + derBytes, err := x509.MarshalPKIXPublicKey(ecPublicKey) + if err != nil { + return "", fmt.Errorf("failed to marshal public key: %s %w", identifier, err) + } + + pemBlock := &pem.Block{ + Type: "PUBLIC KEY", + Bytes: derBytes, + } + pemBytes := pem.EncodeToMemory(pemBlock) + if pemBytes == nil { + return "", fmt.Errorf("failed to encode public key to PEM: %s", identifier) + } + return string(pemBytes), nil + } + return "", fmt.Errorf("no EC Key found with the given identifier: %s", identifier) } func (s StandardCrypto) RSADecrypt(_ crypto.Hash, keyID string, _ string, ciphertext []byte) ([]byte, error) { @@ -135,17 +206,96 @@ func (s StandardCrypto) RSAPublicKeyAsJSON(keyID string) (string, error) { return string(jsonPublicKey), nil } -func (s StandardCrypto) GenerateNanoTDFSymmetricKey([]byte) ([]byte, error) { - return nil, errNotImplemented +func (s StandardCrypto) GenerateNanoTDFSymmetricKey(ephemeralPublicKeyBytes []byte) ([]byte, error) { + ephemeralECDSAPublicKey, err := ConvertEphemeralPublicKeyBytesToECDSAPublicKey(ephemeralPublicKeyBytes) + if err != nil { + return nil, err + } + derBytes, err := x509.MarshalPKIXPublicKey(ephemeralECDSAPublicKey) + if err != nil { + return nil, fmt.Errorf("failed to marshal ECDSA public key: %w", err) + } + pemBlock := &pem.Block{ + Type: "PUBLIC KEY", + Bytes: derBytes, + } + ephemeralECDSAPublicKeyPEM := pem.EncodeToMemory(pemBlock) + + symmetricKey, err := ocrypto.ComputeECDHKey([]byte(s.ecKeys[0].ecPrivateKeyPem), ephemeralECDSAPublicKeyPEM) + if err != nil { + return nil, fmt.Errorf("ocrypto.ComputeECDHKey failed: %w", err) + } + + key, err := ocrypto.CalculateHKDF(versionSalt(), symmetricKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) + } + + return key, nil } func (s StandardCrypto) GenerateEphemeralKasKeys() (any, []byte, error) { - return 0, nil, errNotImplemented + ephemeralKeyPair, err := ocrypto.NewECKeyPair(ocrypto.ECCModeSecp256r1) + if err != nil { + return nil, nil, fmt.Errorf("ocrypto.NewECKeyPair failed: %w", err) + } + + pubKeyInPem, err := ephemeralKeyPair.PublicKeyInPemFormat() + if err != nil { + return nil, nil, fmt.Errorf("failed to get public key in PEM format: %w", err) + } + pubKeyBytes := []byte(pubKeyInPem) + + privKey, err := ocrypto.ConvertToECDHPrivateKey(ephemeralKeyPair.PrivateKey) + if err != nil { + return nil, nil, fmt.Errorf("failed to convert provate key to ECDH: %w", err) + } + return privKey, pubKeyBytes, nil } -func (s StandardCrypto) GenerateNanoTDFSessionKey(any, []byte) ([]byte, error) { - return nil, errNotImplemented +func (s StandardCrypto) GenerateNanoTDFSessionKey(privateKey any, ephemeralPublicKeyPEM []byte) ([]byte, error) { + ecdhKey, err := ocrypto.ConvertToECDHPrivateKey(privateKey) + if err != nil { + return nil, fmt.Errorf("GenerateNanoTDFSessionKey failed to ConvertToECDHPrivateKey: %w", err) + } + ephemeralECDHPublicKey, err := ocrypto.ECPubKeyFromPem(ephemeralPublicKeyPEM) + if err != nil { + return nil, fmt.Errorf("GenerateNanoTDFSessionKey failed to ocrypto.ECPubKeyFromPem: %w", err) + } + // shared secret + sessionKey, err := ecdhKey.ECDH(ephemeralECDHPublicKey) + if err != nil { + return nil, fmt.Errorf("GenerateNanoTDFSessionKey failed to ecdhKey.ECDH: %w", err) + } + + salt := versionSalt() + derivedKey, err := ocrypto.CalculateHKDF(salt, sessionKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) + } + return derivedKey, nil +} + +func ConvertEphemeralPublicKeyBytesToECDSAPublicKey(ephemeralPublicKeyBytes []byte) (*ecdsa.PublicKey, error) { + // Converting ephemeralPublicKey byte array to *big.Int + x, y := elliptic.UnmarshalCompressed(elliptic.P256(), ephemeralPublicKeyBytes) + if x == nil { + return nil, errors.New("failed to unmarshal compressed public key") + } + // Creating ecdsa.PublicKey from *big.Int + ephemeralECDSAPublicKey := &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: x, + Y: y, + } + return ephemeralECDSAPublicKey, nil } func (s StandardCrypto) Close() { } + +func versionSalt() []byte { + digest := sha256.New() + digest.Write([]byte(kNanoTDFMagicStringAndVersion)) + return digest.Sum(nil) +} diff --git a/service/kas/access/provider.go b/service/kas/access/provider.go index 0deef7ae9..b0fc38062 100644 --- a/service/kas/access/provider.go +++ b/service/kas/access/provider.go @@ -9,6 +9,7 @@ import ( otdf "github.com/opentdf/platform/sdk" "github.com/opentdf/platform/service/internal/logger" "github.com/opentdf/platform/service/internal/security" + "github.com/opentdf/platform/service/pkg/serviceregistry" ) const ( @@ -23,10 +24,11 @@ type Provider struct { AttributeSvc *url.URL CryptoProvider security.CryptoProvider Logger *logger.Logger + Config *serviceregistry.ServiceConfig } -// TODO: Not sure what we want to check here? -func (p Provider) IsReady(ctx context.Context) error { +func (p *Provider) IsReady(ctx context.Context) error { + // TODO: Not sure what we want to check here? slog.DebugContext(ctx, "checking readiness of kas service") return nil } diff --git a/service/kas/access/publicKey.go b/service/kas/access/publicKey.go index e98076ebf..2672381b9 100644 --- a/service/kas/access/publicKey.go +++ b/service/kas/access/publicKey.go @@ -29,7 +29,12 @@ func (p *Provider) LegacyPublicKey(ctx context.Context, in *kaspb.LegacyPublicKe return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) } if algorithm == algorithmEc256 { - pem, err = p.CryptoProvider.ECPublicKey("unknown") + ecCertIDInf := p.Config.ExtraProps["eccertid"] + ecCertID, ok := ecCertIDInf.(string) + if !ok { + return nil, errors.New("services.kas.eccertid is not a string") + } + pem, err = p.CryptoProvider.ECCertificate(ecCertID) if err != nil { slog.ErrorContext(ctx, "CryptoProvider.ECPublicKey failed", "err", err) return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) @@ -51,7 +56,7 @@ func (p *Provider) LegacyPublicKey(ctx context.Context, in *kaspb.LegacyPublicKe func (p *Provider) PublicKey(ctx context.Context, in *kaspb.PublicKeyRequest) (*kaspb.PublicKeyResponse, error) { algorithm := in.GetAlgorithm() if algorithm == algorithmEc256 { - ecPublicKeyPem, err := p.CryptoProvider.ECPublicKey("unknown") + ecPublicKeyPem, err := p.CryptoProvider.ECPublicKey("123") if err != nil { slog.ErrorContext(ctx, "CryptoProvider.ECPublicKey failed", "err", err) return nil, errors.Join(ErrConfig, status.Error(codes.Internal, "configuration error")) diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index fcaa43d1c..919dad5ff 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "crypto" - "crypto/ecdh" "crypto/ecdsa" "crypto/hmac" "crypto/rsa" @@ -16,6 +15,7 @@ import ( "encoding/pem" "errors" "fmt" + "log/slog" "strings" "time" @@ -56,8 +56,9 @@ type entityInfo struct { } const ( - ErrUser = Error("request error") - ErrInternal = Error("internal error") + kNanoTDFGMACLength = 8 + ErrUser = Error("request error") + ErrInternal = Error("internal error") ) func err400(s string) error { @@ -272,9 +273,18 @@ func (p *Provider) Rewrap(ctx context.Context, in *kaspb.RewrapRequest) (*kaspb. } if body.Algorithm == "ec:secp256r1" { - return p.nanoTDFRewrap(body) + rsp, err := p.nanoTDFRewrap(ctx, body, entityInfo) + if err != nil { + slog.ErrorContext(ctx, "rewrap nano", "err", err) + } + p.Logger.DebugContext(ctx, "rewrap nano", "rsp", rsp) + return rsp, err + } + rsp, err := p.tdf3Rewrap(ctx, body, entityInfo) + if err != nil { + slog.ErrorContext(ctx, "rewrap tdf3", "err", err) } - return p.tdf3Rewrap(ctx, body, entityInfo) + return rsp, err } func (p *Provider) tdf3Rewrap(ctx context.Context, body *RequestBody, entity *entityInfo) (*kaspb.RewrapResponse, error) { @@ -345,19 +355,60 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, body *RequestBody, entity *en }, nil } -func (p *Provider) nanoTDFRewrap(body *RequestBody) (*kaspb.RewrapResponse, error) { +func (p *Provider) nanoTDFRewrap(ctx context.Context, body *RequestBody, entity *entityInfo) (*kaspb.RewrapResponse, error) { headerReader := bytes.NewReader(body.KeyAccess.Header) - header, err := sdk.ReadNanoTDFHeader(headerReader) + header, _, err := sdk.NewNanoTDFHeaderFromReader(headerReader) if err != nil { return nil, fmt.Errorf("failed to parse NanoTDF header: %w", err) } - symmetricKey, err := p.CryptoProvider.GenerateNanoTDFSymmetricKey(header.EphemeralPublicKey.Key) + symmetricKey, err := p.CryptoProvider.GenerateNanoTDFSymmetricKey(header.EphemeralKey) if err != nil { return nil, fmt.Errorf("failed to generate symmetric key: %w", err) } + // check the policy binding + digest := ocrypto.CalculateSHA256(header.EncryptedPolicyBody) + binding := digest[len(digest)-kNanoTDFGMACLength:] + if !bytes.Equal(binding, header.PolicyBinding) { + return nil, fmt.Errorf("policy binding check failed") + } + + // extract the policy + policy, err := extractNanoPolicy(symmetricKey, header) + if err != nil { + return nil, fmt.Errorf("Error extracting policy: %w", err) + } + + // do the access check + tok := &authorization.Token{ + Id: "rewrap-tok", + Jwt: entity.Token, + } + + access, err := canAccess(ctx, tok, *policy, p.SDK) + + auditPolicy := transformAuditPolicy(policy, entity.Token, *p.Logger) + + if err != nil { + p.Logger.WarnContext(ctx, "Could not perform access decision!", "err", err) + err := p.Logger.Audit.RewrapFailure(ctx, *auditPolicy) + if err != nil { + p.Logger.ErrorContext(ctx, "failed to audit rewrap failure", "err", err) + } + return nil, err403("forbidden") + } + + if !access { + p.Logger.WarnContext(ctx, "Access Denied; no reason given") + err := p.Logger.Audit.RewrapFailure(ctx, *auditPolicy) + if err != nil { + p.Logger.ErrorContext(ctx, "failed to audit rewrap failure", "err", err) + } + return nil, err403("forbidden") + } + pub, ok := body.PublicKey.(*ecdsa.PublicKey) if !ok { return nil, fmt.Errorf("failed to extract public key: %w", err) @@ -371,10 +422,11 @@ func (p *Provider) nanoTDFRewrap(body *RequestBody) (*kaspb.RewrapResponse, erro } privateKeyHandle, publicKeyHandle, err := p.CryptoProvider.GenerateEphemeralKasKeys() + if err != nil { return nil, fmt.Errorf("failed to generate keypair: %w", err) } - sessionKey, err := p.CryptoProvider.GenerateNanoTDFSessionKey(privateKeyHandle, pubKeyBytes) + sessionKey, err := p.CryptoProvider.GenerateNanoTDFSessionKey(privateKeyHandle, []byte(body.ClientPublicKey)) if err != nil { return nil, fmt.Errorf("failed to generate session key: %w", err) } @@ -384,29 +436,39 @@ func (p *Provider) nanoTDFRewrap(body *RequestBody) (*kaspb.RewrapResponse, erro return nil, fmt.Errorf("failed to encrypt key: %w", err) } - // see explanation why Public Key starts at position 2 - //https://github.com/wqx0532/hyperledger-fabric-gm-1/blob/master/bccsp/pkcs11/pkcs11.go#L480 - pubGoKey, err := ecdh.P256().NewPublicKey(publicKeyHandle[2:]) + return &kaspb.RewrapResponse{ + EntityWrappedKey: cipherText, + SessionPublicKey: string(publicKeyHandle), + SchemaVersion: schemaVersion, + }, nil +} + +func extractNanoPolicy(symmetricKey []byte, header sdk.NanoTDFHeader) (*Policy, error) { + gcm, err := ocrypto.NewAESGcm(symmetricKey) if err != nil { - return nil, fmt.Errorf("failed to make public key") // Handle error, e.g., invalid public key format + return nil, fmt.Errorf("crypto.NewAESGcm:%w", err) } - pbk, err := x509.MarshalPKIXPublicKey(pubGoKey) + const ( + kIvLen = 12 + ) + iv := make([]byte, kIvLen) + tagSize, err := sdk.SizeOfAuthTagForCipher(header.GetCipher()) if err != nil { - return nil, fmt.Errorf("failed to convert public Key to PKIX") + return nil, fmt.Errorf("SizeOfAuthTagForCipher failed:%w", err) } - pemBlock := &pem.Block{ - Type: "PUBLIC KEY", - Bytes: pbk, + policyData, err := gcm.DecryptWithIVAndTagSize(iv, header.EncryptedPolicyBody, tagSize) + if err != nil { + return nil, fmt.Errorf("Error decrypting policy body:%w", err) } - pemString := string(pem.EncodeToMemory(pemBlock)) - return &kaspb.RewrapResponse{ - EntityWrappedKey: cipherText, - SessionPublicKey: pemString, - SchemaVersion: schemaVersion, - }, nil + var policy Policy + err = json.Unmarshal(policyData, &policy) + if err != nil { + return nil, fmt.Errorf("Error unmarshalling policy:%w", err) + } + return &policy, nil } func wrapKeyAES(sessionKey, dek []byte) ([]byte, error) { diff --git a/service/kas/kas.go b/service/kas/kas.go index c93ca7634..3a2a9a657 100644 --- a/service/kas/kas.go +++ b/service/kas/kas.go @@ -35,6 +35,7 @@ func NewRegistration() serviceregistry.Registration { CryptoProvider: srp.OTDF.CryptoProvider, SDK: srp.SDK, Logger: srp.Logger, + Config: &srp.Config, } if err := srp.RegisterReadinessCheck("kas", p.IsReady); err != nil {