diff --git a/docker-compose.yaml b/docker-compose.yaml index ab10d677a..279c5ac8f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -58,3 +58,21 @@ services: retries: 10 ports: - "5432:5432" + + openldap: + image: osixia/openldap:1.5.0 + environment: + LDAP_ORGANISATION: "Development" + LDAP_DOMAIN: "localhost" + LDAP_ADMIN_PASSWORD: "mypassword" + LDAP_READONLY_USER_USERNAME: "readonly" + LDAP_READONLY_USER_PASSWORD: "mypassword" + ports: + - "389:389" + - "636:636" + vault: + image: hashicorp/vault + environment: + VAULT_DEV_ROOT_TOKEN_ID: "myroot" + ports: + - "8200:8200" diff --git a/examples/cmd/decrypt.go b/examples/cmd/decrypt.go index 7af44cc15..7c25abab5 100644 --- a/examples/cmd/decrypt.go +++ b/examples/cmd/decrypt.go @@ -28,11 +28,7 @@ func decrypt(cmd *cobra.Command, args []string) error { tdfFile := args[0] // Create new client - client, err := sdk.New(cmd.Context().Value(RootConfigKey).(*ExampleConfig).PlatformEndpoint, - sdk.WithInsecureConn(), - sdk.WithClientCredentials("opentdf-sdk", "secret", nil), - sdk.WithTokenEndpoint("http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token"), - ) + client, err := sdk.New(cmd.Context().Value(RootConfigKey).(*ExampleConfig).PlatformEndpoint) if err != nil { return err } diff --git a/examples/cmd/encrypt.go b/examples/cmd/encrypt.go index aad24a84c..ccc7c87b3 100644 --- a/examples/cmd/encrypt.go +++ b/examples/cmd/encrypt.go @@ -2,6 +2,7 @@ package cmd import ( "encoding/json" + "fmt" "os" "strings" @@ -30,11 +31,7 @@ func encrypt(cmd *cobra.Command, args []string) error { // Create new offline client - client, err := sdk.New(cmd.Context().Value(RootConfigKey).(*ExampleConfig).PlatformEndpoint, - sdk.WithInsecureConn(), - sdk.WithClientCredentials("opentdf-sdk", "secret", nil), - sdk.WithTokenEndpoint("http://localhost:8888/auth/realms/opentdf/protocol/openid-connect/token"), - ) + client, err := sdk.New(cmd.Context().Value(RootConfigKey).(*ExampleConfig).PlatformEndpoint) if err != nil { return err } @@ -49,7 +46,7 @@ func encrypt(cmd *cobra.Command, args []string) error { //sdk.WithDataAttributes("https://example.com/attr/attr1/value/value1"), sdk.WithKasInformation( sdk.KASInfo{ - URL: "http://localhost:8080", + URL: fmt.Sprintf("https://%s", cmd.Flag("platformEndpoint").Value.String()), PublicKey: "", })) if err != nil { diff --git a/examples/go.mod b/examples/go.mod index c374cd86d..a33bf1501 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -5,6 +5,7 @@ go 1.22.2 require ( github.com/arkavo-org/opentdf-platform/protocol/go v0.0.0-00010101000000-000000000000 github.com/arkavo-org/opentdf-platform/sdk v0.0.0-00010101000000-000000000000 + github.com/go-ldap/ldap/v3 v3.4.6 github.com/spf13/cobra v1.8.0 google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.33.0 @@ -18,9 +19,11 @@ replace ( require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240221180331-f05a6f4403ce.1 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/arkavo-org/opentdf-platform/lib/ocrypto v0.0.0-00010101000000-000000000000 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/protobuf v1.5.4 // indirect diff --git a/examples/go.sum b/examples/go.sum index 9485ea0a1..5a339ebe2 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -4,10 +4,14 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= +github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.12.0 h1:rbICA+XZFwrBef2Odk++0LjFvClNCJGRK+fsrP254Ts= github.com/Microsoft/hcsshim v0.12.0/go.mod h1:RZV12pcHCXQ42XnlQ3pz6FZfmrC1C+R4gaOHhRNML1g= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= +github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/containerd/containerd v1.7.14 h1:H/XLzbnGuenZEGK+v0RkwTdv2u1QFAruMe5N0GNPJwA= @@ -19,6 +23,7 @@ github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHf github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/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.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -33,6 +38,10 @@ 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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA= +github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= +github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -51,6 +60,7 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= @@ -117,8 +127,10 @@ github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyh github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/testcontainers/testcontainers-go v0.28.0 h1:1HLm9qm+J5VikzFDYhOd+Zw12NtOl+8drH2E8nTY1r8= @@ -127,6 +139,7 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= @@ -137,20 +150,57 @@ go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGX go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +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/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 h1:oqta3O3AnlWbmIE3bFnWbu4bRxZjfbWCp0cKSuZh01E= google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7/go.mod h1:VQW3tUculP/D4B+xVCo+VgSq8As6wA9ZjHl//pmk+6s= diff --git a/examples/main.go b/examples/main.go index 33fc8f5f1..4fdc4f538 100644 --- a/examples/main.go +++ b/examples/main.go @@ -1,9 +1,58 @@ package main import ( + "fmt" "github.com/arkavo-org/opentdf-platform/examples/cmd" + "github.com/go-ldap/ldap/v3" + "log" ) func main() { cmd.Execute() + //ExampleConn_Search() + //ExampleConn_Bind() +} + +func ExampleConn_Bind() { + l, err := ldap.DialURL("ldap://localhost:389") + if err != nil { + log.Fatal(err) + } + defer func(l *ldap.Conn) { + err := l.Close() + if err != nil { + + } + }(l) + + err = l.Bind("cn=admin", "admin") + if err != nil { + log.Fatal(err) + } +} + +// This example demonstrates how to use the search interface +func ExampleConn_Search() { + l, err := ldap.DialURL("ldap://localhost:389") + if err != nil { + log.Fatal(err) + } + defer l.Close() + + searchRequest := ldap.NewSearchRequest( + "dc=example,dc=com", // The base dn to search + ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, + "(&(objectClass=organizationalPerson))", // The filter to apply + []string{"dn", "cn"}, // A list attributes to retrieve + nil, + ) + + sr, err := l.Search(searchRequest) + if err != nil { + log.Fatal(err) + } + + for _, entry := range sr.Entries { + fmt.Printf("%s: %v\n", entry.DN, entry.GetAttributeValue("cn")) + } } diff --git a/sdk/auth_config.go b/sdk/auth_config.go index 39bb53aeb..6cfe8a608 100644 --- a/sdk/auth_config.go +++ b/sdk/auth_config.go @@ -3,12 +3,19 @@ package sdk import ( "bytes" "context" + "crypto/rsa" + "crypto/tls" + "crypto/x509" "encoding/json" + "encoding/pem" "fmt" "io" + "io/ioutil" + "log" "log/slog" "net/http" "net/url" + "os" "strings" "time" @@ -116,8 +123,12 @@ func (a *AuthConfig) makeKASRequest(kasPath string, body *RequestBody) (*http.Re string(requestBodyData), } token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) - - signingRSAPrivateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(a.dpopPrivateKeyPEM)) + // load private key + privateKeyBytes, err := os.ReadFile("../pep.key") + if err != nil { + return nil, fmt.Errorf("private key not found: %w", err) + } + signingRSAPrivateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBytes) if err != nil { return nil, fmt.Errorf("jwt.ParseRSAPrivateKeyFromPEM failed: %w", err) } @@ -146,12 +157,46 @@ func (a *AuthConfig) makeKASRequest(kasPath string, body *RequestBody) (*http.Re // add required headers request.Header = http.Header{ - kContentTypeKey: {kContentTypeJSONValue}, - kAuthorizationKey: {fmt.Sprintf("Bearer %s", a.accessToken)}, - kAcceptKey: {kContentTypeJSONValue}, + kContentTypeKey: {kContentTypeJSONValue}, + //kAuthorizationKey: {fmt.Sprintf("Bearer %s", a.accessToken)}, + kAcceptKey: {kContentTypeJSONValue}, } - - client := &http.Client{} + // Load the client's certificate and private key + certificate, err := tls.LoadX509KeyPair("../pep.crt", "../pep.key") + if err != nil { + log.Fatalf("could not load client key pair: %s", err) + } + caCert, err := os.ReadFile("../ca.crt") + if err != nil { + log.Fatal(err) + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig := &tls.Config{ + MinVersion: tls.VersionTLS12, + Certificates: []tls.Certificate{certificate}, + RootCAs: caCertPool, + } + transport := &http.Transport{ + TLSClientConfig: tlsConfig, + } + client := &http.Client{Transport: transport} + + // ++++++++++ + //kasPubKeyURL, err := url.JoinPath(fmt.Sprintf("%v/v2", kasURL), kasPath) + //if err != nil { + // return nil, fmt.Errorf("url.Parse failed: %w", err) + //} + //request, err = http.NewRequestWithContext(context.Background(), http.MethodGet, kasPubKeyURL, nil) + //if err != nil { + // return nil, fmt.Errorf("http.NewRequestWithContext failed: %w", err) + //} + //// add required headers + //request.Header = http.Header{ + // kAcceptKey: {kContentTypeJSONValue}, + //} + // ++++++++++ response, err := client.Do(request) if err != nil { @@ -163,10 +208,44 @@ func (a *AuthConfig) makeKASRequest(kasPath string, body *RequestBody) (*http.Re } func (a *AuthConfig) unwrap(keyAccess KeyAccess, policy string) ([]byte, error) { + // load certificate + certificateBytes, err := os.ReadFile("../pep.crt") + if err != nil { + return nil, fmt.Errorf("private key not found: %w", err) + } + + block, _ := pem.Decode(certificateBytes) + if block == nil { + log.Fatalf("Failed to parse the PEM certificate") + } + + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + log.Fatalf("Failed to parse the DER encoded certificate: %v", err) + } + + pubKey := cert.PublicKey + + // Use the public key... + pubKey, ok := pubKey.(*rsa.PublicKey) + if !ok { + log.Fatalf("It's not an RSA key") + } + // Marshal the public key to ASN.1 DER encoding. + pubASN1, err := x509.MarshalPKIXPublicKey(pubKey) + if err != nil { + log.Fatalf("Cannot Marshal rsa key to DER format: %s", err) + } + // Create a pem.Block with the public key. + pubBytes := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: pubASN1, + }) requestBody := RequestBody{ - KeyAccess: keyAccess, - Policy: policy, - ClientPublicKey: a.dpopPublicKeyPEM, + KeyAccess: keyAccess, + Policy: policy, + // replace with public key from certificate + ClientPublicKey: string(pubBytes), } response, err := a.makeKASRequest(kRewrapV2, &requestBody) @@ -193,7 +272,11 @@ func (a *AuthConfig) unwrap(keyAccess KeyAccess, policy string) ([]byte, error) return nil, fmt.Errorf("io.ReadAll failed: %w", err) } - key, err := getWrappedKey(rewrapResponseBody, a.dpopPrivateKeyPEM) + privateKeyPEM, err := ioutil.ReadFile("../pep.key") + if err != nil { + log.Fatalf("Failed to read the PEM certificate: %v", err) + } + key, err := getWrappedKey(rewrapResponseBody, string(privateKeyPEM)) if err != nil { return nil, fmt.Errorf("failed to unwrap the wrapped key:%w", err) } @@ -247,7 +330,27 @@ func (*AuthConfig) getPublicKey(kasInfo KASInfo) (string, error) { kAcceptKey: {kContentTypeJSONValue}, } - client := &http.Client{} + // Load the client's certificate and private key + certificate, err := tls.LoadX509KeyPair("../pep.crt", "../pep.key") + if err != nil { + log.Fatalf("could not load client key pair: %s", err) + } + caCert, err := os.ReadFile("../ca.crt") + if err != nil { + log.Fatal(err) + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + tlsConfig := &tls.Config{ + MinVersion: tls.VersionTLS12, + Certificates: []tls.Certificate{certificate}, + RootCAs: caCertPool, + } + transport := &http.Transport{ + TLSClientConfig: tlsConfig, + } + client := &http.Client{Transport: transport} response, err := client.Do(request) defer func() { @@ -259,6 +362,9 @@ func (*AuthConfig) getPublicKey(kasInfo KASInfo) (string, error) { slog.Error("Fail to close HTTP response") } }() + if err != nil { + return "", fmt.Errorf("client.Do error: %w", err) + } if response.StatusCode != kHTTPOk { return "", fmt.Errorf("client.Do failed: %w", err) } diff --git a/sdk/kas_client.go b/sdk/kas_client.go index c570561b3..9bc728e69 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -157,13 +157,13 @@ func (k *KASClient) getRewrapRequest(keyAccess KeyAccess, policy string) (*kas.R return nil, fmt.Errorf("failed to sign the token: %w", err) } - accessToken, err := k.accessTokenSource.AccessToken() - if err != nil { - return nil, fmt.Errorf("error getting access token: %w", err) - } + //accessToken, err := k.accessTokenSource.AccessToken() + //if err != nil { + // fmt.Printf("warn getting access token: %v", err) + //} rewrapRequest := kas.RewrapRequest{ - Bearer: string(accessToken), + //Bearer: string(accessToken), SignedRequestToken: string(signedToken), } return &rewrapRequest, nil diff --git a/sdk/sdk.go b/sdk/sdk.go index cf718ca03..b5c7b197a 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -2,8 +2,11 @@ package sdk import ( "crypto/tls" + "crypto/x509" "errors" + "log" "log/slog" + "os" "github.com/arkavo-org/opentdf-platform/protocol/go/authorization" "github.com/arkavo-org/opentdf-platform/protocol/go/kasregistry" @@ -11,7 +14,6 @@ import ( "github.com/arkavo-org/opentdf-platform/protocol/go/policy/namespaces" "github.com/arkavo-org/opentdf-platform/protocol/go/policy/resourcemapping" "github.com/arkavo-org/opentdf-platform/protocol/go/policy/subjectmapping" - "github.com/arkavo-org/opentdf-platform/sdk/auth" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -39,8 +41,26 @@ type SDK struct { } func New(platformEndpoint string, opts ...Option) (*SDK, error) { + // Load the client's certificate and private key + certificate, err := tls.LoadX509KeyPair("../pep.crt", "../pep.key") + if err != nil { + log.Fatalf("could not load client key pair: %s", err) + } + // Create a certificate pool from the certificate authority + certPool := x509.NewCertPool() + ca, err := os.ReadFile("../ca.crt") + if err != nil { + log.Fatalf("could not read ca certificate: %s", err) + } + + // Append the client certificates from the CA + if ok := certPool.AppendCertsFromPEM(ca); !ok { + log.Fatalf("failed to append client certs") + } tlsConfig := tls.Config{ - MinVersion: tls.VersionTLS12, + MinVersion: tls.VersionTLS12, + Certificates: []tls.Certificate{certificate}, + RootCAs: certPool, } // Set default options @@ -54,25 +74,26 @@ func New(platformEndpoint string, opts ...Option) (*SDK, error) { } // once we change KAS to use standard DPoP we can put this all in the `build()` method + // no need for this with PKI dialOptions := append([]grpc.DialOption{}, cfg.build()...) - accessTokenSource, err := buildIDPTokenSource(cfg) - if err != nil { - return nil, err - } - if accessTokenSource != nil { - interceptor := auth.NewTokenAddingInterceptor(accessTokenSource) - dialOptions = append(dialOptions, grpc.WithUnaryInterceptor(interceptor.AddCredentials)) - } + //accessTokenSource, err := buildIDPTokenSource(cfg) + //if err != nil { + // return nil, err + //} + //if accessTokenSource != nil { + // interceptor := auth.NewTokenAddingInterceptor(accessTokenSource) + // dialOptions = append(dialOptions, grpc.WithUnaryInterceptor(interceptor.AddCredentials)) + //} var unwrapper Unwrapper - if cfg.authConfig == nil { - unwrapper, err = newKASClient(dialOptions, accessTokenSource) - if err != nil { - return nil, err - } - } else { - unwrapper = cfg.authConfig - } + //if cfg.authConfig == nil { + // unwrapper, err = newKASClient(dialOptions, accessTokenSource) + // if err != nil { + // return nil, err + // } + //} else { + unwrapper = cfg.authConfig + //} var ( defaultConn *grpc.ClientConn diff --git a/sdk/tdf.go b/sdk/tdf.go index 0d873006e..9527772cf 100644 --- a/sdk/tdf.go +++ b/sdk/tdf.go @@ -46,7 +46,7 @@ const ( kClientPublicKey = "clientPublicKey" kSignedRequestToken = "signedRequestToken" kKasURL = "url" - kRewrapV2 = "/v2/rewrap" + kRewrapV2 = "kas/v2/rewrap" kAuthorizationKey = "Authorization" kContentTypeKey = "Content-Type" kAcceptKey = "Accept" diff --git a/sdk/tdf_config.go b/sdk/tdf_config.go index f218adb04..d6aee3fd7 100644 --- a/sdk/tdf_config.go +++ b/sdk/tdf_config.go @@ -9,7 +9,7 @@ import ( const ( tdf3KeySize = 2048 defaultSegmentSize = 2 * 1024 * 1024 // 2mb - kasPublicKeyPath = "/kas_public_key" + kasPublicKeyPath = "kas/kas_public_key" ) type TDFFormat = int diff --git a/service/internal/server/server.go b/service/internal/server/server.go index ce86bab49..aab2dbb69 100644 --- a/service/internal/server/server.go +++ b/service/internal/server/server.go @@ -3,11 +3,14 @@ package server import ( "context" "crypto/tls" + "crypto/x509" "errors" "fmt" + "log" "log/slog" "net" "net/http" + "os" "strings" "time" @@ -59,6 +62,7 @@ type GRPCConfig struct { type TLSConfig struct { Enabled bool `yaml:"enabled" default:"false"` Cert string `yaml:"cert"` + CACert string `yaml:"ca_cert" default:"../ca.crt"` Key string `yaml:"key"` } @@ -198,6 +202,7 @@ func httpGrpcHandlerFunc(h http.Handler, g *grpc.Server) http.Handler { if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") { g.ServeHTTP(w, r) } else { + h.ServeHTTP(w, r) } }) @@ -317,9 +322,19 @@ func loadTLSConfig(config TLSConfig) (*tls.Config, error) { if err != nil { return nil, fmt.Errorf("failed to load tls cert: %w", err) } - + // Load CA certificate + caCert, err := os.ReadFile(config.CACert) + if err != nil { + log.Fatalf("failed to load CA cert: %v", err) + } + caPool := x509.NewCertPool() + if ok := caPool.AppendCertsFromPEM(caCert); !ok { + log.Fatalf("failed to append CA cert to pool") + } return &tls.Config{ Certificates: []tls.Certificate{cert}, + ClientCAs: caPool, + ClientAuth: tls.RequireAndVerifyClientCert, MinVersion: tls.VersionTLS12, NextProtos: []string{"h2", "http/1.1"}, }, nil