mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-22 20:00:18 +00:00
NOISSUE - Update cocos to match certs changes (#520)
CI / checkproto (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (agent) (push) Has been cancelled
CI / test (cli) (push) Has been cancelled
CI / test (cmd) (push) Has been cancelled
CI / test (internal) (push) Has been cancelled
CI / test (manager, true) (push) Has been cancelled
CI / test (pkg) (push) Has been cancelled
CI / upload-coverage (push) Has been cancelled
CI / checkproto (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (agent) (push) Has been cancelled
CI / test (cli) (push) Has been cancelled
CI / test (cmd) (push) Has been cancelled
CI / test (internal) (push) Has been cancelled
CI / test (manager, true) (push) Has been cancelled
CI / test (pkg) (push) Has been cancelled
CI / upload-coverage (push) Has been cancelled
* pass domain id to agent environment Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * update generated files Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * use certs sdk directly Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * remove redundant variables Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * use agent certs token for csr Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * update certs and add token to create req Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * fix atls Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * add agent token to certificate provider Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * pass certs token to agent Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * use sdk for csr Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * update atls Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * fix tests Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * address comments Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * remove unused structs Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * update tests Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * lint Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * fix tests Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * lint Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * remove unused domain id Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * refactor tests and remove unused struct fields Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * refactor(atls): remove CAClient and inline CA certificate issuance Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * lint' Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * increase coverage Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * fix bug in certs sdk and certificate provider Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * update certs Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> * fix pkg stress Signed-off-by: WashingtonKK <washingtonkigan@gmail.com> --------- Signed-off-by: WashingtonKK <washingtonkigan@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0be724386b
commit
0ffc2d17cf
+18
-10
@@ -6,16 +6,24 @@ Agent service provides a barebones HTTP and gRPC API and Service interface imple
|
||||
|
||||
The service is configured using the environment variables from the following table. Note that any unset variables will be replaced with their default values.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------------------------ |
|
||||
| AGENT_LOG_LEVEL | Log level for agent service (debug, info, warn, error) | debug |
|
||||
| AGENT_CVM_GRPC_HOST | Agent service gRPC host | "" |
|
||||
| AGENT_CVM_GRPC_PORT | Agent service gRPC port | 7001 |
|
||||
| AGENT_CVM_GRPC_SERVER_CERT | Path to gRPC server certificate in pem format | "" |
|
||||
| AGENT_CVM_GRPC_SERVER_KEY | Path to gRPC server key in pem format | "" |
|
||||
| AGENT_CVM_GRPC_SERVER_CA_CERTS | Path to gRPC server CA certificate | "" |
|
||||
| AGENT_CVM_GRPC_CLIENT_CA_CERTS | Path to gRPC client CA certificate | "" |
|
||||
| AGENT_CVM_CA_URL | URL for CA service, if provided it will be used for certificate generation, used only with aTLS at the moment | "" |
|
||||
| Variable | Description | Default |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
||||
| AGENT_LOG_LEVEL | Log level for agent service (debug, info, warn, error) | debug |
|
||||
| AGENT_VMPL | VMPL (Virtual Machine Privilege Level) for AMD SEV-SNP attestation (0-3) | 2 |
|
||||
| AGENT_GRPC_HOST | Agent service gRPC host address | 0.0.0.0 |
|
||||
| AGENT_CVM_GRPC_HOST | Agent service gRPC host | "" |
|
||||
| AGENT_CVM_GRPC_PORT | Agent service gRPC port | 7001 |
|
||||
| AGENT_CVM_GRPC_SERVER_CERT | Path to gRPC server certificate in pem format | "" |
|
||||
| AGENT_CVM_GRPC_SERVER_KEY | Path to gRPC server key in pem format | "" |
|
||||
| AGENT_CVM_GRPC_SERVER_CA_CERTS | Path to gRPC server CA certificate | "" |
|
||||
| AGENT_CVM_GRPC_CLIENT_CA_CERTS | Path to gRPC client CA certificate | "" |
|
||||
| AGENT_CVM_CA_URL | URL for CA service, if provided it will be used for certificate generation, used only with aTLS at the moment | "" |
|
||||
| AGENT_CVM_ID | Unique identifier for the CVM (Confidential Virtual Machine) | "" |
|
||||
| AGENT_CERTS_TOKEN | Authentication token for certificate service access | "" |
|
||||
| AGENT_MAA_URL | Microsoft Azure Attestation service URL for Azure attestation | https://sharedeus2.eus2.attest.azure.net |
|
||||
| AGENT_OS_BUILD | Operating system build information for attestation | UVC |
|
||||
| AGENT_OS_DISTRO | Operating system distribution information for attestation | UVC |
|
||||
| AGENT_OS_TYPE | Operating system type information for attestation | UVC |
|
||||
|
||||
## Deployment
|
||||
|
||||
|
||||
+18
-13
@@ -14,8 +14,8 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/certs/sdk"
|
||||
mglog "github.com/absmach/supermq/logger"
|
||||
"github.com/absmach/supermq/pkg/prometheus"
|
||||
"github.com/caarlos0/env/v11"
|
||||
@@ -39,22 +39,21 @@ import (
|
||||
|
||||
const (
|
||||
svcName = "agent"
|
||||
defSvcGRPCPort = "7002"
|
||||
retryInterval = 5 * time.Second
|
||||
envPrefixCVMGRPC = "AGENT_CVM_GRPC_"
|
||||
storageDir = "/var/lib/cocos/agent"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
||||
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
||||
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||
AgentOSType string `env:"AGENT_OS_TYPE" envDefault:"UVC"`
|
||||
LogLevel string `env:"AGENT_LOG_LEVEL" envDefault:"debug"`
|
||||
Vmpl int `env:"AGENT_VMPL" envDefault:"2"`
|
||||
AgentGrpcHost string `env:"AGENT_GRPC_HOST" envDefault:"0.0.0.0"`
|
||||
CAUrl string `env:"AGENT_CVM_CA_URL" envDefault:""`
|
||||
CVMId string `env:"AGENT_CVM_ID" envDefault:""`
|
||||
CertsToken string `env:"AGENT_CERTS_TOKEN" envDefault:""`
|
||||
AgentMaaURL string `env:"AGENT_MAA_URL" envDefault:"https://sharedeus2.eus2.attest.azure.net"`
|
||||
AgentOSBuild string `env:"AGENT_OS_BUILD" envDefault:"UVC"`
|
||||
AgentOSDistro string `env:"AGENT_OS_DISTRO" envDefault:"UVC"`
|
||||
AgentOSType string `env:"AGENT_OS_TYPE" envDefault:"UVC"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -167,7 +166,13 @@ func main() {
|
||||
var certProvider atls.CertificateProvider
|
||||
|
||||
if ccPlatform != attestation.NoCC {
|
||||
certProvider, err = atls.NewProvider(provider, ccPlatform, cfg.CVMId, cfg.CAUrl)
|
||||
var certsSDK sdk.SDK
|
||||
if cfg.CAUrl != "" {
|
||||
certsSDK = sdk.NewSDK(sdk.Config{
|
||||
CertsURL: cfg.CAUrl,
|
||||
})
|
||||
}
|
||||
certProvider, err = atls.NewProvider(provider, ccPlatform, cfg.CertsToken, cfg.CVMId, certsSDK)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("failed to create certificate provider: %s", err))
|
||||
exitCode = 1
|
||||
|
||||
+5
-6
@@ -35,12 +35,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
svcName = "manager"
|
||||
envPrefixGRPC = "MANAGER_GRPC_"
|
||||
envPrefixHTTP = "MANAGER_HTTP_"
|
||||
envPrefixQemu = "MANAGER_QEMU_"
|
||||
clientBufferSize = 100
|
||||
defSvcHTTPPort = "7003"
|
||||
svcName = "manager"
|
||||
envPrefixGRPC = "MANAGER_GRPC_"
|
||||
envPrefixHTTP = "MANAGER_HTTP_"
|
||||
envPrefixQemu = "MANAGER_QEMU_"
|
||||
defSvcHTTPPort = "7003"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
|
||||
@@ -15,10 +15,10 @@ require (
|
||||
github.com/virtee/sev-snp-measure-go v0.0.0-20240530153610-e6e8dc9b6877
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0
|
||||
go.opentelemetry.io/otel/trace v1.38.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/sync v0.16.0
|
||||
google.golang.org/grpc v1.75.0
|
||||
google.golang.org/protobuf v1.36.8
|
||||
golang.org/x/crypto v0.42.0
|
||||
golang.org/x/sync v0.17.0
|
||||
google.golang.org/grpc v1.75.1
|
||||
google.golang.org/protobuf v1.36.9
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -63,7 +63,6 @@ require (
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
@@ -72,7 +71,6 @@ require (
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
|
||||
github.com/zeebo/errs v1.4.0 // indirect
|
||||
@@ -84,18 +82,18 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
google.golang.org/api v0.247.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
moul.io/http2curl v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/absmach/certs v0.17.0
|
||||
github.com/absmach/certs v0.17.1-0.20251006092614-ffc1e886a28a
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
@@ -114,9 +112,9 @@ require (
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.23.0
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
||||
@@ -125,7 +123,7 @@ require (
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/term v0.35.0
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -34,8 +34,10 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/absmach/certs v0.17.0 h1:b2PrRUzDTeVUznbWVTg2xCZeCKTIqx+W/qnEOzkNXPA=
|
||||
github.com/absmach/certs v0.17.0/go.mod h1:B+qydTGoBxyGR7FTpuCT9CreppNmpaGP68AJvinXDgE=
|
||||
github.com/absmach/certs v0.17.1-0.20251006092614-ffc1e886a28a h1:894h9JmlnXp4/Qzpkauk/bd/6QapxXdBcc8i+88Sf1Q=
|
||||
github.com/absmach/certs v0.17.1-0.20251006092614-ffc1e886a28a/go.mod h1:m6CWmAio930laR1TLZ3HhQna4f9KmSyyUGfD8EFZHwE=
|
||||
github.com/absmach/senml v1.0.8 h1:+opem/r4g6c6eA/JLyCIuksyEhj7eBdysY3pEmy1mqo=
|
||||
github.com/absmach/senml v1.0.8/go.mod h1:DRhzHLgvQoIUHroBgpFrSWso+bJZO9E96RlHAHy+VRI=
|
||||
github.com/absmach/supermq v0.18.1 h1:JRLP6rfSzZoHgRGPfwNSmzJ7a4K4b4Dvz2nCmR32rxI=
|
||||
github.com/absmach/supermq v0.18.1/go.mod h1:dYnFOIcGQzZ1WpYt1qNv1g609WmOWYzWCBBRjPQV7Uk=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -62,6 +64,10 @@ github.com/danko-miladinovic/go-tpm-tools v0.0.0-20250228160324-1ebcfd79567c/go.
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0 h1:qTQ38m7oIyd4GAed/QkUZyPFNMnvVWyazGXRwvOt5zk=
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0/go.mod h1:gpoRV3VzrEY1a9dWAYV6T1U7YzfgttXdd/ZzL1s9OZM=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.4.0+incompatible h1:KVC7bz5zJY/4AZe/78BIvCnPsLaC9T/zh72xnlrTTOk=
|
||||
@@ -70,6 +76,8 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/edgelesssys/go-azguestattestation v0.0.0-20250408071817-8c4457b235ff h1:V6A5kD0+c1Qg4X72Lg+zxhCZk+par436sQdgLvMCBBc=
|
||||
github.com/edgelesssys/go-azguestattestation v0.0.0-20250408071817-8c4457b235ff/go.mod h1:Lz4QaomI4wU2YbatD4/W7vatW2Q35tnkoJezB1clscc=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
||||
@@ -84,8 +92,12 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
|
||||
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
|
||||
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI=
|
||||
@@ -101,6 +113,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
|
||||
@@ -147,10 +161,18 @@ github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25d
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f h1:7LYC+Yfkj3CTRcShK0KOL/w6iTiKyqqBA9a41Wnggw8=
|
||||
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk=
|
||||
github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
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/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
@@ -161,6 +183,18 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lestrrat-go/blackmagic v1.0.3 h1:94HXkVLxkZO9vJI/w2u1T0DAoprShFd13xtnSINtDWs=
|
||||
github.com/lestrrat-go/blackmagic v1.0.3/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
|
||||
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
|
||||
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
|
||||
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
|
||||
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
|
||||
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
|
||||
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
|
||||
github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVfecA=
|
||||
github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU=
|
||||
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
|
||||
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
@@ -181,8 +215,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 h1:xzZOeCMQLA/W198ZkdVdt4EKFKJtS26B773zNU377ZY=
|
||||
@@ -190,19 +222,23 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587/go.mod h1
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rubenv/sql-migrate v1.8.0 h1:dXnYiJk9k3wetp7GfQbKJcPHjVJL6YK19tKj8t2Ns0o=
|
||||
github.com/rubenv/sql-migrate v1.8.0/go.mod h1:F2bGFBwCU+pnmbtNYDeKvSuvL6lBVtXDXUUv5t+u1qw=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825 h1:SqNaL9udBIc026SGNEuEuiVL0/hw9fXxM5qrFhWGkdE=
|
||||
github.com/sammyoina/sev-snp-measure-go v0.0.0-20241202151803-ef189f0ff825/go.mod h1:dEkBe8JnxU5itNjZDEQINFd7f7l4DtjfqRuzPQcit4w=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
|
||||
@@ -221,6 +257,8 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
|
||||
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
|
||||
@@ -254,11 +292,13 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=
|
||||
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -275,8 +315,8 @@ golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKl
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -302,8 +342,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -321,15 +361,13 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc=
|
||||
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
+11
-2
@@ -34,6 +34,7 @@ type CreateReq struct {
|
||||
AgentCvmServerUrl string `protobuf:"bytes,5,opt,name=agent_cvm_server_url,json=agentCvmServerUrl,proto3" json:"agent_cvm_server_url,omitempty"`
|
||||
AgentCvmCaUrl string `protobuf:"bytes,6,opt,name=agent_cvm_ca_url,json=agentCvmCaUrl,proto3" json:"agent_cvm_ca_url,omitempty"`
|
||||
Ttl string `protobuf:"bytes,7,opt,name=ttl,proto3" json:"ttl,omitempty"`
|
||||
AgentCertsToken string `protobuf:"bytes,8,opt,name=agent_certs_token,json=agentCertsToken,proto3" json:"agent_certs_token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -117,6 +118,13 @@ func (x *CreateReq) GetTtl() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CreateReq) GetAgentCertsToken() string {
|
||||
if x != nil {
|
||||
return x.AgentCertsToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CreateRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ForwardedPort string `protobuf:"bytes,1,opt,name=forwarded_port,json=forwardedPort,proto3" json:"forwarded_port,omitempty"`
|
||||
@@ -441,7 +449,7 @@ var File_manager_manager_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_manager_manager_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x15manager/manager.proto\x12\amanager\x1a\x1bgoogle/protobuf/empty.proto\"\xbb\x02\n" +
|
||||
"\x15manager/manager.proto\x12\amanager\x1a\x1bgoogle/protobuf/empty.proto\"\xe7\x02\n" +
|
||||
"\tCreateReq\x12&\n" +
|
||||
"\x0fagent_log_level\x18\x01 \x01(\tR\ragentLogLevel\x126\n" +
|
||||
"\x18agent_cvm_server_ca_cert\x18\x02 \x01(\fR\x14agentCvmServerCaCert\x12/\n" +
|
||||
@@ -449,7 +457,8 @@ const file_manager_manager_proto_rawDesc = "" +
|
||||
"\x15agent_cvm_client_cert\x18\x04 \x01(\fR\x12agentCvmClientCert\x12/\n" +
|
||||
"\x14agent_cvm_server_url\x18\x05 \x01(\tR\x11agentCvmServerUrl\x12'\n" +
|
||||
"\x10agent_cvm_ca_url\x18\x06 \x01(\tR\ragentCvmCaUrl\x12\x10\n" +
|
||||
"\x03ttl\x18\a \x01(\tR\x03ttl\"I\n" +
|
||||
"\x03ttl\x18\a \x01(\tR\x03ttl\x12*\n" +
|
||||
"\x11agent_certs_token\x18\b \x01(\tR\x0fagentCertsToken\"I\n" +
|
||||
"\tCreateRes\x12%\n" +
|
||||
"\x0eforwarded_port\x18\x01 \x01(\tR\rforwardedPort\x12\x15\n" +
|
||||
"\x06cvm_id\x18\x02 \x01(\tR\x05cvmId\"\"\n" +
|
||||
|
||||
@@ -24,6 +24,7 @@ message CreateReq{
|
||||
string agent_cvm_server_url = 5;
|
||||
string agent_cvm_ca_url = 6;
|
||||
string ttl = 7;
|
||||
string agent_certs_token = 8;
|
||||
}
|
||||
|
||||
message CreateRes{
|
||||
|
||||
+2
-1
@@ -27,7 +27,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
hashLength = 32
|
||||
persistenceDir = "/tmp/cocos"
|
||||
agentLogLevelKey = "AGENT_LOG_LEVEL"
|
||||
agentCvmGrpcUrlKey = "AGENT_CVM_GRPC_URL"
|
||||
@@ -35,6 +34,7 @@ const (
|
||||
agentCvmClientKey = "AGENT_CVM_GRPC_CLIENT_KEY"
|
||||
agentCvmServerCaCertKey = "AGENT_CVM_GRPC_SERVER_CA_CERTS"
|
||||
agentCvmId = "AGENT_CVM_ID"
|
||||
agentCaToken = "AGENT_CERTS_TOKEN"
|
||||
agentCvmCaUrl = "AGENT_CVM_CA_URL"
|
||||
defClientCertPath = "/etc/certs/cert.pem"
|
||||
defClientKeyPath = "/etc/certs/key.pem"
|
||||
@@ -446,6 +446,7 @@ func tmpEnvironment(id string, req *CreateReq) (string, error) {
|
||||
agentLogLevelKey: req.AgentLogLevel,
|
||||
agentCvmGrpcUrlKey: req.AgentCvmServerUrl,
|
||||
agentCvmId: id,
|
||||
agentCaToken: req.AgentCertsToken,
|
||||
agentCvmCaUrl: req.AgentCvmCaUrl,
|
||||
}
|
||||
|
||||
|
||||
+2
-101
@@ -3,23 +3,9 @@
|
||||
package atls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/certs"
|
||||
certscli "github.com/absmach/certs/cli"
|
||||
"github.com/absmach/certs/errors"
|
||||
certssdk "github.com/absmach/certs/sdk"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,6 +24,7 @@ var (
|
||||
// CertificateSubject contains certificate subject information.
|
||||
type CertificateSubject struct {
|
||||
Organization string
|
||||
CommonName string
|
||||
Country string
|
||||
Province string
|
||||
Locality string
|
||||
@@ -49,6 +36,7 @@ type CertificateSubject struct {
|
||||
func DefaultCertificateSubject() CertificateSubject {
|
||||
return CertificateSubject{
|
||||
Organization: "Ultraviolet",
|
||||
CommonName: "Ultraviolet",
|
||||
Country: "Serbia",
|
||||
Province: "",
|
||||
Locality: "Belgrade",
|
||||
@@ -57,93 +45,6 @@ func DefaultCertificateSubject() CertificateSubject {
|
||||
}
|
||||
}
|
||||
|
||||
// CAClient handles communication with Certificate Authority.
|
||||
type CAClient struct {
|
||||
baseURL string
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
type CSRRequest struct {
|
||||
CSR string `json:"csr,omitempty"`
|
||||
}
|
||||
|
||||
func NewCAClient(baseURL string) *CAClient {
|
||||
return &CAClient{
|
||||
baseURL: baseURL,
|
||||
client: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CAClient) RequestCertificate(csrMetadata certs.CSRMetadata, privateKey *ecdsa.PrivateKey, cvmID string, ttl time.Duration) ([]byte, error) {
|
||||
csr, sdkerr := certscli.CreateCSR(csrMetadata, privateKey)
|
||||
if sdkerr != nil {
|
||||
return nil, fmt.Errorf("failed to create CSR: %w", sdkerr)
|
||||
}
|
||||
|
||||
request := CSRRequest{CSR: string(csr.CSR)}
|
||||
requestData, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal CSR request: %w", err)
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("certs/csrs/%s", cvmID)
|
||||
query := url.Values{}
|
||||
query.Add("ttl", ttl.String())
|
||||
requestURL := fmt.Sprintf("%s/%s?%s", c.baseURL, endpoint, query.Encode())
|
||||
|
||||
_, responseBody, err := c.processRequest(http.MethodPost, requestURL, requestData, nil, http.StatusOK)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to process CA request: %w", err)
|
||||
}
|
||||
|
||||
var cert certssdk.Certificate
|
||||
if err := json.Unmarshal(responseBody, &cert); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal certificate response: %w", err)
|
||||
}
|
||||
|
||||
cleanCertificateString := strings.ReplaceAll(cert.Certificate, "\\n", "\n")
|
||||
block, rest := pem.Decode([]byte(cleanCertificateString))
|
||||
|
||||
if len(rest) != 0 {
|
||||
return nil, fmt.Errorf("failed to decode certificate PEM: unexpected remaining data")
|
||||
}
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to decode certificate PEM: no PEM block found")
|
||||
}
|
||||
|
||||
return block.Bytes, nil
|
||||
}
|
||||
|
||||
func (c *CAClient) processRequest(method, reqURL string, data []byte, headers map[string]string, expectedRespCodes ...int) (http.Header, []byte, errors.SDKError) {
|
||||
req, err := http.NewRequest(method, reqURL, bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return make(http.Header), []byte{}, errors.NewSDKError(err)
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
for key, value := range headers {
|
||||
req.Header.Add(key, value)
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return make(http.Header), []byte{}, errors.NewSDKError(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
sdkErr := errors.CheckError(resp, expectedRespCodes...)
|
||||
if sdkErr != nil {
|
||||
return make(http.Header), []byte{}, sdkErr
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return make(http.Header), []byte{}, errors.NewSDKError(err)
|
||||
}
|
||||
|
||||
return resp.Header, body, nil
|
||||
}
|
||||
|
||||
func extractNonceFromSNI(serverName string) ([]byte, error) {
|
||||
if len(serverName) < len(nonceSuffix) || !hasNonceSuffix(serverName) {
|
||||
return nil, fmt.Errorf("invalid server name: %s", serverName)
|
||||
|
||||
+281
-87
@@ -12,19 +12,18 @@ import (
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/certs"
|
||||
certssdk "github.com/absmach/certs/sdk"
|
||||
sdkmocks "github.com/absmach/certs/sdk/mocks"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
"github.com/google/go-sev-guest/abi"
|
||||
"github.com/google/go-sev-guest/proto/check"
|
||||
@@ -39,10 +38,70 @@ import (
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
const sevProductNameMilan = "Milan"
|
||||
const (
|
||||
sevProductNameMilan = "Milan"
|
||||
)
|
||||
|
||||
var policy = attestation.Config{Config: &check.Config{Policy: &check.Policy{}, RootOfTrust: &check.RootOfTrust{}}, PcrConfig: &attestation.PcrConfig{}}
|
||||
|
||||
func generateTestCertPEM(t *testing.T) string {
|
||||
return generateTestCertPEMWithSubject(t, "test")
|
||||
}
|
||||
|
||||
func generateTestCertPEMWithSubject(t *testing.T, commonName string) string {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err)
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: commonName,
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(365 * 24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certDER,
|
||||
})
|
||||
|
||||
return strings.ReplaceAll(string(certPEM), "\n", "\\n")
|
||||
}
|
||||
|
||||
func generateTestCertificateWithExtensions(t *testing.T, extensions []pkix.Extension) *x509.Certificate {
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err)
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "test",
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(365 * 24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
ExtraExtensions: extensions,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
cert, err := x509.ParseCertificate(certDER)
|
||||
require.NoError(t, err)
|
||||
|
||||
return cert
|
||||
}
|
||||
|
||||
// TestCertificateSubject tests the CertificateSubject functionality.
|
||||
func TestDefaultCertificateSubject(t *testing.T) {
|
||||
subject := DefaultCertificateSubject()
|
||||
@@ -58,15 +117,15 @@ func TestDefaultCertificateSubject(t *testing.T) {
|
||||
// TestUnifiedCertificateGenerator tests the unified certificate generator.
|
||||
func TestUnifiedCertificateGenerator(t *testing.T) {
|
||||
t.Run("SelfSignedGenerator", func(t *testing.T) {
|
||||
generator, err := NewProvider(nil, attestation.SNPvTPM, "", "")
|
||||
generator, err := NewProvider(nil, attestation.SNPvTPM, "", "", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, generator)
|
||||
})
|
||||
|
||||
t.Run("CASignedGenerator", func(t *testing.T) {
|
||||
caURL := "https://example.com/ca"
|
||||
cvmID := "test-cvm-id"
|
||||
generator, err := NewProvider(nil, attestation.SNPvTPM, caURL, cvmID)
|
||||
mockSDK := sdkmocks.NewSDK(t)
|
||||
|
||||
generator, err := NewProvider(nil, attestation.SNPvTPM, "test-token", "test-cvm-id", mockSDK)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, generator)
|
||||
})
|
||||
@@ -204,19 +263,27 @@ func TestNewProvider(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
|
||||
t.Run("SelfSignedProvider", func(t *testing.T) {
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "")
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, provider)
|
||||
})
|
||||
|
||||
t.Run("CASignedProvider", func(t *testing.T) {
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "https://example.com", "test-cvm")
|
||||
t.Run("CASignedProviderWithSDK", func(t *testing.T) {
|
||||
mockSDK := sdkmocks.NewSDK(t)
|
||||
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "test-token", "test-cvm-id", mockSDK)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, provider)
|
||||
})
|
||||
|
||||
t.Run("SelfSignedProviderNilSDK", func(t *testing.T) {
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "test-token", "test-cvm-id", nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, provider)
|
||||
})
|
||||
|
||||
t.Run("InvalidPlatformType", func(t *testing.T) {
|
||||
_, err := NewProvider(mockProvider, attestation.PlatformType(999), "", "")
|
||||
_, err := NewProvider(mockProvider, attestation.PlatformType(999), "", "", nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
@@ -514,47 +581,6 @@ func TestVerifyCertificateExtension(t *testing.T) {
|
||||
|
||||
// Helper functions
|
||||
|
||||
func createMockCAServer(t *testing.T) *httptest.Server {
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Create a valid test certificate
|
||||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
template := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Test CA"},
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &privKey.PublicKey, privKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certDER,
|
||||
})
|
||||
|
||||
mockCert := certssdk.Certificate{
|
||||
Certificate: string(certPEM),
|
||||
}
|
||||
|
||||
response, _ := json.Marshal(mockCert)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(response)
|
||||
}))
|
||||
}
|
||||
|
||||
func prepVerifyAttReport(t *testing.T) *sevsnp.Attestation {
|
||||
file, err := os.ReadFile("../../attestation.bin")
|
||||
require.NoError(t, err)
|
||||
@@ -686,40 +712,199 @@ func TestCertificateVerification(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessRequestEdgeCases tests CAClient.processRequest edge cases.
|
||||
func TestProcessRequestEdgeCases(t *testing.T) {
|
||||
client := NewCAClient("http://example.com")
|
||||
// TestAttestedCAProvider tests the CA-signed certificate provider.
|
||||
func TestAttestedCAProvider(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
attestationProvider, err := NewAttestationProvider(mockProvider, attestation.SNPvTPM)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("InvalidURL", func(t *testing.T) {
|
||||
_, _, err := client.processRequest("GET", "://invalid-url", nil, nil, http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
subject := DefaultCertificateSubject()
|
||||
cvmID := "test-cvm-id"
|
||||
agentToken := "test-token"
|
||||
|
||||
t.Run("NewAttestedCAProvider", func(t *testing.T) {
|
||||
provider := NewAttestedCAProvider(attestationProvider, subject, nil, cvmID, agentToken)
|
||||
assert.NotNil(t, provider)
|
||||
})
|
||||
|
||||
t.Run("NetworkError", func(t *testing.T) {
|
||||
_, _, err := client.processRequest("GET", "http://nonexistent-domain-12345.com", nil, nil, http.StatusOK)
|
||||
t.Run("SetTTL", func(t *testing.T) {
|
||||
provider := NewAttestedCAProvider(attestationProvider, subject, nil, cvmID, agentToken)
|
||||
|
||||
newTTL := time.Hour * 48
|
||||
provider.(*attestedCertificateProvider).SetTTL(newTTL)
|
||||
|
||||
attestedProvider := provider.(*attestedCertificateProvider)
|
||||
assert.Equal(t, newTTL, attestedProvider.ttl)
|
||||
})
|
||||
}
|
||||
|
||||
// TestCASignedCertificateErrors tests error cases in CA-signed certificate generation.
|
||||
func TestCASignedCertificateErrors(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
attestationProvider, err := NewAttestationProvider(mockProvider, attestation.SNPvTPM)
|
||||
require.NoError(t, err)
|
||||
|
||||
subject := DefaultCertificateSubject()
|
||||
cvmID := "test-cvm-id"
|
||||
agentToken := "test-token"
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
certificate string
|
||||
sdkError error
|
||||
expectedError string
|
||||
}{
|
||||
{"SDKIssueError", "", errors.NewSDKError(errors.New("SDK error")), "SDK error"},
|
||||
{"InvalidPEMWithRemainingData", "-----BEGIN CERTIFICATE-----\\nVGVzdA==\\n-----END CERTIFICATE-----\\nExtra data here", nil, "unexpected remaining data"},
|
||||
{"NoPEMBlockFound", "", nil, "no PEM block found"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
mockSDK := sdkmocks.NewSDK(t)
|
||||
expectedCSR := certs.CSR{CSR: []byte("test-csr")}
|
||||
mockSDK.On("CreateCSR", mock.Anything, mock.Anything).Return(expectedCSR, errors.SDKError(nil))
|
||||
mockSDK.On("IssueFromCSRInternal", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(certssdk.Certificate{Certificate: c.certificate}, c.sdkError)
|
||||
|
||||
provider := NewAttestedCAProvider(attestationProvider, subject, mockSDK, cvmID, agentToken)
|
||||
attestedProvider := provider.(*attestedCertificateProvider)
|
||||
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
extension := pkix.Extension{
|
||||
Id: SNPvTPMOID,
|
||||
Value: []byte("test-data"),
|
||||
}
|
||||
|
||||
_, err = attestedProvider.generateCASignedCertificate(privateKey, extension)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), c.expectedError)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetCertificateErrors tests error paths in certificate generation.
|
||||
func TestGetCertificateErrors(t *testing.T) {
|
||||
t.Run("InvalidServerNameFormat", func(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
attestationProvider, err := NewAttestationProvider(mockProvider, attestation.SNPvTPM)
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewAttestedProvider(attestationProvider, DefaultCertificateSubject())
|
||||
|
||||
clientHello := &tls.ClientHelloInfo{
|
||||
ServerName: "invalid-format",
|
||||
}
|
||||
|
||||
_, err = provider.GetCertificate(clientHello)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to extract nonce")
|
||||
})
|
||||
|
||||
t.Run("CustomHeaders", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "test-value", r.Header.Get("Custom-Header"))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer server.Close()
|
||||
t.Run("AttestationProviderError", func(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
mockProvider.On("Attestation", mock.Anything, mock.Anything).Return(nil, errors.New("attestation failed"))
|
||||
|
||||
headers := map[string]string{"Custom-Header": "test-value"}
|
||||
_, _, err := client.processRequest("GET", server.URL, nil, headers, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
attestationProvider, err := NewAttestationProvider(mockProvider, attestation.SNPvTPM)
|
||||
require.NoError(t, err)
|
||||
|
||||
provider := NewAttestedProvider(attestationProvider, DefaultCertificateSubject())
|
||||
|
||||
nonce := make([]byte, 64)
|
||||
_, err = rand.Read(nonce)
|
||||
require.NoError(t, err)
|
||||
|
||||
serverName := hex.EncodeToString(nonce) + ".nonce"
|
||||
clientHello := &tls.ClientHelloInfo{ServerName: serverName}
|
||||
|
||||
_, err = provider.GetCertificate(clientHello)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to get attestation")
|
||||
})
|
||||
|
||||
t.Run("UnexpectedStatusCode", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}))
|
||||
defer server.Close()
|
||||
t.Run("CASignedCertificateError", func(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
mockProvider.On("Attestation", mock.Anything, mock.Anything).Return([]byte("test-attestation"), nil)
|
||||
|
||||
_, _, err := client.processRequest("GET", server.URL, nil, nil, http.StatusOK)
|
||||
attestationProvider, err := NewAttestationProvider(mockProvider, attestation.SNPvTPM)
|
||||
require.NoError(t, err)
|
||||
|
||||
mockSDK := sdkmocks.NewSDK(t)
|
||||
expectedCSR := certs.CSR{CSR: []byte("test-csr")}
|
||||
sdkErr := errors.NewSDKError(errors.New("CA error"))
|
||||
mockSDK.On("CreateCSR", mock.Anything, mock.Anything).Return(expectedCSR, errors.SDKError(nil))
|
||||
mockSDK.On("IssueFromCSRInternal", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(certssdk.Certificate{}, sdkErr)
|
||||
|
||||
provider := NewAttestedCAProvider(attestationProvider, DefaultCertificateSubject(), mockSDK, "test-cvm", "test-token")
|
||||
|
||||
nonce := make([]byte, 64)
|
||||
_, err = rand.Read(nonce)
|
||||
require.NoError(t, err)
|
||||
|
||||
serverName := hex.EncodeToString(nonce) + ".nonce"
|
||||
clientHello := &tls.ClientHelloInfo{ServerName: serverName}
|
||||
|
||||
_, err = provider.GetCertificate(clientHello)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to generate certificate")
|
||||
})
|
||||
}
|
||||
|
||||
// TestCertificateVerificationEdgeCases tests edge cases in certificate verification.
|
||||
func TestCertificateVerificationEdgeCases(t *testing.T) {
|
||||
tempDir, err := os.MkdirTemp("", "policy")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
attestationPB := prepVerifyAttReport(t)
|
||||
err = setAttestationPolicy(attestationPB, tempDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("VerifyPeerCertificateWithMultipleCerts", func(t *testing.T) {
|
||||
verifier := NewCertificateVerifier(nil)
|
||||
cert1 := createSelfSignedCert(t)
|
||||
cert2 := createSelfSignedCert(t)
|
||||
nonce := generateNonce(t)
|
||||
|
||||
err := verifier.VerifyPeerCertificate([][]byte{cert1.Raw, cert2.Raw}, nil, nonce)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "attestation extension not found")
|
||||
})
|
||||
|
||||
t.Run("VerifyAttestationExtensionWithNoExtensions", func(t *testing.T) {
|
||||
cert := createSelfSignedCert(t)
|
||||
verifier := certificateVerifier{}
|
||||
nonce := generateNonce(t)
|
||||
|
||||
err := verifier.verifyAttestationExtension(cert, nonce)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "attestation extension not found")
|
||||
})
|
||||
|
||||
t.Run("VerifyAttestationExtensionWithWrongOID", func(t *testing.T) {
|
||||
wrongOID := asn1.ObjectIdentifier{1, 2, 3, 4, 5}
|
||||
extension := pkix.Extension{
|
||||
Id: wrongOID,
|
||||
Value: []byte("test-data"),
|
||||
}
|
||||
|
||||
cert := generateTestCertificateWithExtensions(t, []pkix.Extension{extension})
|
||||
verifier := certificateVerifier{}
|
||||
nonce := generateNonce(t)
|
||||
|
||||
err := verifier.verifyAttestationExtension(cert, nonce)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "attestation extension not found")
|
||||
})
|
||||
|
||||
t.Run("VerifyCertificateExtensionPlatformVerifierError", func(t *testing.T) {
|
||||
verifier := certificateVerifier{}
|
||||
invalidPlatformType := attestation.PlatformType(999)
|
||||
|
||||
err := verifier.verifyCertificateExtension([]byte("test-extension"), []byte("test-pubkey"), []byte("test-nonce"), invalidPlatformType)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "unsupported platform type")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -793,7 +978,7 @@ func TestIntegrationScenarios(t *testing.T) {
|
||||
mockProvider.On("Attestation", mock.Anything, mock.Anything).Return([]byte("mock-attestation"), nil)
|
||||
|
||||
// Create provider
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "")
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Generate certificate
|
||||
@@ -826,19 +1011,18 @@ func TestIntegrationScenarios(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("FullCASignedFlow", func(t *testing.T) {
|
||||
// Setup mock CA server
|
||||
mockServer := createMockCAServer(t)
|
||||
defer mockServer.Close()
|
||||
mockSDK := sdkmocks.NewSDK(t)
|
||||
expectedCSR := certs.CSR{CSR: []byte("test-csr")}
|
||||
expectedCert := certssdk.Certificate{Certificate: generateTestCertPEM(t)}
|
||||
mockSDK.On("CreateCSR", mock.Anything, mock.Anything).Return(expectedCSR, errors.SDKError(nil))
|
||||
mockSDK.On("IssueFromCSRInternal", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(expectedCert, errors.SDKError(nil))
|
||||
|
||||
// Setup mock provider
|
||||
mockProvider := new(mocks.Provider)
|
||||
mockProvider.On("Attestation", mock.Anything, mock.Anything).Return([]byte("mock-attestation"), nil)
|
||||
|
||||
// Create CA-signed provider
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, mockServer.URL, "test-cvm")
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "test-token", "test-cvm-id", mockSDK)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Generate certificate
|
||||
nonce := make([]byte, 64)
|
||||
_, err = rand.Read(nonce)
|
||||
require.NoError(t, err)
|
||||
@@ -847,8 +1031,18 @@ func TestIntegrationScenarios(t *testing.T) {
|
||||
clientHello := &tls.ClientHelloInfo{ServerName: serverName}
|
||||
|
||||
cert, err := provider.GetCertificate(clientHello)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cert)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cert)
|
||||
require.NotEmpty(t, cert.Certificate)
|
||||
require.NotNil(t, cert.PrivateKey)
|
||||
|
||||
parsedCert, err := x509.ParseCertificate(cert.Certificate[0])
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotNil(t, parsedCert.Subject)
|
||||
|
||||
mockProvider.AssertExpectations(t)
|
||||
mockSDK.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -857,7 +1051,7 @@ func TestConcurrentAccess(t *testing.T) {
|
||||
mockProvider := new(mocks.Provider)
|
||||
mockProvider.On("Attestation", mock.Anything, mock.Anything).Return([]byte("mock-attestation"), nil)
|
||||
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "")
|
||||
provider, err := NewProvider(mockProvider, attestation.SNPvTPM, "", "", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
const numGoroutines = 10
|
||||
|
||||
@@ -9,11 +9,14 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/certs"
|
||||
sdk "github.com/absmach/certs/sdk"
|
||||
"github.com/ultravioletrs/cocos/pkg/attestation"
|
||||
)
|
||||
|
||||
@@ -25,7 +28,8 @@ type CertificateProvider interface {
|
||||
// AttestedCertificateProvider provides attested TLS certificates.
|
||||
type attestedCertificateProvider struct {
|
||||
attestationProvider AttestationProvider
|
||||
caClient *CAClient
|
||||
certsSDK sdk.SDK
|
||||
agentToken string
|
||||
subject CertificateSubject
|
||||
useCA bool
|
||||
cvmID string
|
||||
@@ -50,12 +54,13 @@ func NewAttestedProvider(
|
||||
func NewAttestedCAProvider(
|
||||
attestationProvider AttestationProvider,
|
||||
subject CertificateSubject,
|
||||
caURL, cvmID string,
|
||||
certsSDK sdk.SDK, cvmID, agentToken string,
|
||||
) CertificateProvider {
|
||||
return &attestedCertificateProvider{
|
||||
attestationProvider: attestationProvider,
|
||||
subject: subject,
|
||||
caClient: NewCAClient(caURL),
|
||||
certsSDK: certsSDK,
|
||||
agentToken: agentToken,
|
||||
useCA: true,
|
||||
cvmID: cvmID,
|
||||
ttl: time.Hour * 24 * 365, // Default 1 year
|
||||
@@ -136,6 +141,7 @@ func (p *attestedCertificateProvider) generateCASignedCertificate(privateKey *ec
|
||||
csrMetadata := certs.CSRMetadata{
|
||||
Organization: []string{p.subject.Organization},
|
||||
Country: []string{p.subject.Country},
|
||||
CommonName: p.subject.CommonName,
|
||||
Province: []string{p.subject.Province},
|
||||
Locality: []string{p.subject.Locality},
|
||||
StreetAddress: []string{p.subject.StreetAddress},
|
||||
@@ -143,10 +149,30 @@ func (p *attestedCertificateProvider) generateCASignedCertificate(privateKey *ec
|
||||
ExtraExtensions: []pkix.Extension{extension},
|
||||
}
|
||||
|
||||
return p.caClient.RequestCertificate(csrMetadata, privateKey, p.cvmID, p.ttl)
|
||||
csr, sdkerr := p.certsSDK.CreateCSR(csrMetadata, privateKey)
|
||||
if sdkerr != nil {
|
||||
return nil, fmt.Errorf("failed to create CSR: %w", sdkerr)
|
||||
}
|
||||
|
||||
cert, err := p.certsSDK.IssueFromCSRInternal(p.cvmID, p.ttl.String(), string(csr.CSR), p.agentToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cleanCertificateString := strings.ReplaceAll(cert.Certificate, "\\n", "\n")
|
||||
block, rest := pem.Decode([]byte(cleanCertificateString))
|
||||
|
||||
if len(rest) != 0 {
|
||||
return nil, fmt.Errorf("failed to decode certificate PEM: unexpected remaining data")
|
||||
}
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to decode certificate PEM: no PEM block found")
|
||||
}
|
||||
|
||||
return block.Bytes, nil
|
||||
}
|
||||
|
||||
func NewProvider(provider attestation.Provider, platformType attestation.PlatformType, caURL, cvmID string) (CertificateProvider, error) {
|
||||
func NewProvider(provider attestation.Provider, platformType attestation.PlatformType, agentToken, cvmID string, certsSDK sdk.SDK) (CertificateProvider, error) {
|
||||
attestationProvider, err := NewAttestationProvider(provider, platformType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create attestation provider: %w", err)
|
||||
@@ -154,8 +180,8 @@ func NewProvider(provider attestation.Provider, platformType attestation.Platfor
|
||||
|
||||
subject := DefaultCertificateSubject()
|
||||
|
||||
if caURL != "" && cvmID != "" {
|
||||
return NewAttestedCAProvider(attestationProvider, subject, caURL, cvmID), nil
|
||||
if certsSDK != nil {
|
||||
return NewAttestedCAProvider(attestationProvider, subject, certsSDK, cvmID, agentToken), nil
|
||||
}
|
||||
|
||||
return NewAttestedProvider(attestationProvider, subject), nil
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ func main() {
|
||||
|
||||
flagSetParseError := flagSet.Parse(os.Args[1:])
|
||||
if flagSetParseError != nil {
|
||||
log.Fatalf("Error parsing flagas: %v", flagSetParseError)
|
||||
log.Fatalf("Error parsing flags: %v", flagSetParseError)
|
||||
}
|
||||
|
||||
parsingError := !flagSet.Parsed()
|
||||
|
||||
Reference in New Issue
Block a user