diff --git a/api/grpc/grpc.go b/api/grpc/grpc.go new file mode 100644 index 0000000..2b109c1 --- /dev/null +++ b/api/grpc/grpc.go @@ -0,0 +1,53 @@ +package grpc + +import ( + "context" + "fmt" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/neicnordic/sda-download/internal/config" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + + re "github.com/neicnordic/sda-download/internal/reencrypt" +) + +// GetNewHeader +func GetNewHeader(oldHeader []byte, publicKey string) ([]byte, error) { + + // Set up a connection to the server. + log.Debug("Connect to grpc Server to get new header") + var opts []grpc.DialOption + if config.Config.Grpc.CACert != "" && config.Config.Grpc.ServerNameOverride != "" { + creds, err := credentials.NewClientTLSFromFile(config.Config.Grpc.CACert, config.Config.Grpc.ServerNameOverride) + if err != nil { + log.Fatalf("Failed to create TLS credentials: %v", err) + } + opts = append(opts, grpc.WithTransportCredentials(creds)) + } else { + opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } + log.Debugf("grpc connection to: %s:%d", config.Config.Grpc.Host, config.Config.Grpc.Port) + conn, err := grpc.Dial(fmt.Sprintf("%s:%d", config.Config.Grpc.Host, config.Config.Grpc.Port), opts...) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := re.NewReencryptClient(conn) + + // Contact the server and print out its response. + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + r, err := c.ReencryptHeader(ctx, &re.ReencryptRequest{Oldheader: oldHeader, Publickey: publicKey}) + if err != nil { + log.Errorf("could not get the : %v", err) + + return nil, err + } + log.Debugf("Reencrypted Header: %s", string(r.GetHeader())) + + return r.GetHeader(), nil +} diff --git a/api/sda/sda.go b/api/sda/sda.go index 614a11e..86a581d 100644 --- a/api/sda/sda.go +++ b/api/sda/sda.go @@ -2,6 +2,7 @@ package sda import ( "bytes" + "encoding/base64" "errors" "fmt" "io" @@ -12,10 +13,11 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/neicnordic/crypt4gh/keys" "github.com/neicnordic/crypt4gh/model/headers" "github.com/neicnordic/crypt4gh/streaming" + "github.com/neicnordic/sda-download/api/grpc" "github.com/neicnordic/sda-download/api/middleware" - "github.com/neicnordic/sda-download/internal/config" "github.com/neicnordic/sda-download/internal/database" "github.com/neicnordic/sda-download/internal/storage" log "github.com/sirupsen/logrus" @@ -198,8 +200,15 @@ func Download(c *gin.Context) { return } + header := fileDetails.Header + + if c.GetHeader("Crypt4gh-Public-Key") != "" { + clientPublicKey := c.GetHeader("Crypt4gh-Public-Key") + header, _ = grpc.GetNewHeader(header, clientPublicKey) + } + // Stitch file and prepare it for streaming - fileStream, err := stitchFile(fileDetails.Header, file, coordinates) + fileStream, err := stitchFile(header, file, coordinates) if err != nil { log.Errorf("could not prepare file for streaming, %s", err) c.String(http.StatusInternalServerError, "file stream error") @@ -213,11 +222,13 @@ func Download(c *gin.Context) { // stitchFile stitches the header and file body together for Crypt4GHReader // and returns a streamable Reader var stitchFile = func(header []byte, file io.ReadCloser, coordinates *headers.DataEditListHeaderPacket) (*streaming.Crypt4GHReader, error) { + publicKey, privateKey, _ := generateFreshKeyPair() + newheader, _ := grpc.GetNewHeader(header, publicKey) log.Debugf("stitching header to file %s for streaming", file) // Stitch header and file body together - hr := bytes.NewReader(header) + hr := bytes.NewReader(newheader) mr := io.MultiReader(hr, file) - c4ghr, err := streaming.NewCrypt4GHReader(mr, *config.Config.App.Crypt4GHKey, coordinates) + c4ghr, err := streaming.NewCrypt4GHReader(mr, privateKey, coordinates) if err != nil { log.Errorf("failed to create Crypt4GH stream reader, %v", err) @@ -285,3 +296,15 @@ var sendStream = func(w http.ResponseWriter, file io.Reader) { log.Debugf("Sent %d bytes", n) } + +func generateFreshKeyPair() (string, [32]byte, error) { + publicKey, privateKey, err := keys.GenerateKeyPair() + if err != nil { + log.Errorf("Error while generating key pair: %v", err) + + return "", [32]byte{}, err + } + log.Debug("Generated a Fresh Keypair") + + return base64.StdEncoding.EncodeToString(publicKey[:]), privateKey, nil +} diff --git a/cmd/reencrypt/reencrypt.go b/cmd/reencrypt/reencrypt.go new file mode 100644 index 0000000..f874a4b --- /dev/null +++ b/cmd/reencrypt/reencrypt.go @@ -0,0 +1,93 @@ +package main + +import ( + "context" + "fmt" + "net" + "strings" + + log "github.com/sirupsen/logrus" + + "github.com/neicnordic/crypt4gh/keys" + "github.com/neicnordic/crypt4gh/model/headers" + "golang.org/x/crypto/chacha20poly1305" + + "github.com/neicnordic/sda-download/internal/config" + "github.com/neicnordic/sda-download/internal/database" + re "github.com/neicnordic/sda-download/internal/reencrypt" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" +) + +// server struct is used to implement reencrypt.ReEncryptServer. +type server struct { + re.UnimplementedReencryptServer +} + +// init is run before main, it sets up configuration and other required things +func init() { + // Load configuration + conf, err := config.NewConfig("reencrypt") + if err != nil { + log.Panicf("configuration loading failed, reason: %v", err) + } + config.Config = *conf + + // Connect to database + db, err := database.NewDB(conf.DB) + if err != nil { + log.Panicf("database connection failed, reason: %v", err) + } + defer db.Close() + database.DB = db + +} + +// ReencryptHeader implements reencrypt.ReEncryptHeader +func (s *server) ReencryptHeader(ctx context.Context, in *re.ReencryptRequest) (*re.ReencryptResponse, error) { + log.Debugf("Received Public key: %v", in.GetPublickey()) + log.Debugf("Received previous crypt4gh header: %v", in.GetOldheader()) + + // working with the base64 data instead of the full armored key is easier + // as it can be sent in both HTTP headers and HTTP body + newReaderPublicKey, err := keys.ReadPublicKey(strings.NewReader("-----BEGIN CRYPT4GH PUBLIC KEY-----\n" + in.GetPublickey() + "\n-----END CRYPT4GH PUBLIC KEY-----\n")) + if err != nil { + return nil, err + } + + newReaderPublicKeyList := [][chacha20poly1305.KeySize]byte{} + newReaderPublicKeyList = append(newReaderPublicKeyList, newReaderPublicKey) + + log.Debugf("crypt4ghkey: %v", *config.Config.Grpc.Crypt4GHKey) + + newheader, err := headers.ReEncryptHeader(in.GetOldheader(), *config.Config.Grpc.Crypt4GHKey, newReaderPublicKeyList) + if err != nil { + return nil, err + } + + return &re.ReencryptResponse{Header: newheader}, nil +} + +func main() { + lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.Config.Grpc.Host, config.Config.Grpc.Port)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + + var opts []grpc.ServerOption + if config.Config.Grpc.ServerCert != "" && config.Config.Grpc.ServerKey != "" { + creds, err := credentials.NewServerTLSFromFile(config.Config.Grpc.ServerCert, config.Config.Grpc.ServerKey) + if err != nil { + log.Fatalf("Failed to generate credentials: %v", err) + } + opts = []grpc.ServerOption{grpc.Creds(creds)} + } + + s := grpc.NewServer(opts...) + re.RegisterReencryptServer(s, &server{}) + log.Printf("server listening at %v", lis.Addr()) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } + +} diff --git a/dev_utils/compose-no-tls.yml b/dev_utils/compose-no-tls.yml index c66c58b..aca8342 100644 --- a/dev_utils/compose-no-tls.yml +++ b/dev_utils/compose-no-tls.yml @@ -1,5 +1,4 @@ services: - db: command: server /data container_name: db @@ -74,6 +73,25 @@ services: - "8080:8080" restart: always + reencrypt: + command: sda-reencrypt + container_name: reencrypt + depends_on: + db: + condition: service_healthy + environment: + - DB_HOST=db + image: neicnordic/sda-download:latest + build: + context: .. + volumes: + - ./config-notls.yaml:/config.yaml + - ./:/dev_utils/ + mem_limit: 256m + ports: + - "5051:5051" + restart: always + mockauth: command: - /bin/sh diff --git a/dev_utils/config-notls.yaml b/dev_utils/config-notls.yaml index 84f6b7f..fc12e80 100644 --- a/dev_utils/config-notls.yaml +++ b/dev_utils/config-notls.yaml @@ -31,3 +31,7 @@ oidc: # oidc configuration API must have values for "userinfo_endpoint" and "jwks_uri" configuration: url: "http://mockauth:8000/.well-known/openid-configuration" + +grpc: + host: reencrypt + port: 5051 diff --git a/go.mod b/go.mod index 6c51e0c..fa189c1 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/go-playground/validator/v10 v10.15.2 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang/glog v1.1.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -69,12 +70,14 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/arch v0.4.0 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.14.0 golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.13.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect + google.golang.org/grpc v1.59.0 + google.golang.org/protobuf v1.31.0 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 5a96188..85e3061 100644 --- a/go.sum +++ b/go.sum @@ -138,6 +138,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -597,6 +599,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -613,6 +617,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -624,6 +630,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/config/config.go b/internal/config/config.go index 4b5e9ff..c49139a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -34,6 +34,7 @@ type Map struct { DB DatabaseConfig OIDC OIDCConfig Archive storage.Conf + Grpc GrpcConfig } type AppConfig struct { @@ -62,6 +63,13 @@ type AppConfig struct { Middleware string } +type GrpcConfig struct { + AppConfig + + CACert string + ServerNameOverride string +} + type SessionConfig struct { // Session key expiration time in seconds. // Optional. Default value -1 @@ -186,7 +194,11 @@ func NewConfig(app string) (*Map, error) { switch app { case "download": requiredConfVars = []string{ - "db.host", "db.user", "db.password", "db.database", "oidc.configuration.url", "c4gh.filepath", "c4gh.passphrase", + "db.host", "db.user", "db.password", "db.database", "oidc.configuration.url", + } + case "reencrypt": + requiredConfVars = []string{ + "db.host", "db.user", "db.password", "db.database", "c4gh.filepath", "c4gh.passphrase", } default: requiredConfVars = []string{ @@ -224,6 +236,17 @@ func NewConfig(app string) (*Map, error) { if err != nil { return nil, err } + case "reencrypt": + viper.SetDefault("grpc.host", "0.0.0.0") + viper.SetDefault("grpc.port", 5051) + err := c.configDatabase() + if err != nil { + return nil, err + } + err = c.grpcServerConfig() + if err != nil { + return nil, err + } } return c, nil @@ -309,7 +332,7 @@ func (c *Map) configArchive() { } // appConfig sets required settings -func (c *Map) appConfig() error { +func (c *Map) appConfig() (err error) { c.App.Host = viper.GetString("app.host") c.App.Port = viper.GetInt("app.port") c.App.ServerCert = viper.GetString("app.servercert") @@ -322,8 +345,19 @@ func (c *Map) appConfig() error { c.App.Port = 443 } - if viper.IsSet("c4gh.filepath") && viper.IsSet("c4gh.passphrase") { - var err error + if viper.IsSet("grpc.host") { + + c.Grpc.Host = viper.GetString("grpc.host") + c.Grpc.Port = viper.GetInt("grpc.port") + + if viper.IsSet("grpc.cacert") { + c.Grpc.CACert = viper.GetString("grpc.cacert") + } + + if viper.IsSet("grpc.domain") { + c.Grpc.ServerNameOverride = viper.GetString("grpc.domain") + } + } else { c.App.Crypt4GHKey, err = GetC4GHKey() if err != nil { return err @@ -339,6 +373,28 @@ func (c *Map) appConfig() error { return nil } +// grpc-server sets required settings +func (c *Map) grpcServerConfig() (err error) { + c.Grpc.Host = viper.GetString("grpc.host") + c.Grpc.Port = viper.GetInt("grpc.port") + c.Grpc.ServerCert = viper.GetString("grpc.servercert") + c.Grpc.ServerKey = viper.GetString("grpc.serverkey") + + if c.Grpc.Port != 5443 && c.Grpc.Port != 5051 { + c.Grpc.Port = viper.GetInt("grpc.port") + } else if c.Grpc.ServerCert != "" && c.Grpc.ServerKey != "" { + c.Grpc.Port = 5443 + } + + // grpc server is meant to be used with GA4GH key + c.Grpc.Crypt4GHKey, err = GetC4GHKey() + if err != nil { + return err + } + + return nil +} + // sessionConfig controls cookie settings and session cache func (c *Map) sessionConfig() { c.Session.Expiration = time.Duration(viper.GetInt("session.expiration")) * time.Second diff --git a/internal/config/config_test.go b/internal/config/config_test.go index cd2538b..c6652ff 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -14,7 +14,7 @@ import ( ) var requiredConfVars = []string{ - "db.host", "db.user", "db.password", "db.database", "c4gh.filepath", "c4gh.passphrase", "oidc.configuration.url", + "db.host", "db.user", "db.password", "db.database", "oidc.configuration.url", } type TestSuite struct { @@ -26,8 +26,6 @@ func (suite *TestSuite) SetupTest() { viper.Set("db.user", "test") viper.Set("db.password", "test") viper.Set("db.database", "test") - viper.Set("c4gh.filepath", "test") - viper.Set("c4gh.passphrase", "test") viper.Set("oidc.configuration.url", "test") } diff --git a/internal/reencrypt/reencrypt.pb.go b/internal/reencrypt/reencrypt.pb.go new file mode 100644 index 0000000..9e44579 --- /dev/null +++ b/internal/reencrypt/reencrypt.pb.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: internal/reencrypt/reencrypt.proto + +package reencrypt + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The request message containing the publickey and old header +type ReencryptRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Publickey string `protobuf:"bytes,1,opt,name=publickey,proto3" json:"publickey,omitempty"` + Oldheader []byte `protobuf:"bytes,2,opt,name=oldheader,proto3" json:"oldheader,omitempty"` +} + +func (x *ReencryptRequest) Reset() { + *x = ReencryptRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_reencrypt_reencrypt_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReencryptRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReencryptRequest) ProtoMessage() {} + +func (x *ReencryptRequest) ProtoReflect() protoreflect.Message { + mi := &file_internal_reencrypt_reencrypt_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReencryptRequest.ProtoReflect.Descriptor instead. +func (*ReencryptRequest) Descriptor() ([]byte, []int) { + return file_internal_reencrypt_reencrypt_proto_rawDescGZIP(), []int{0} +} + +func (x *ReencryptRequest) GetPublickey() string { + if x != nil { + return x.Publickey + } + return "" +} + +func (x *ReencryptRequest) GetOldheader() []byte { + if x != nil { + return x.Oldheader + } + return nil +} + +// The response message containing the re-encrypted header +type ReencryptResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header []byte `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` +} + +func (x *ReencryptResponse) Reset() { + *x = ReencryptResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_internal_reencrypt_reencrypt_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReencryptResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReencryptResponse) ProtoMessage() {} + +func (x *ReencryptResponse) ProtoReflect() protoreflect.Message { + mi := &file_internal_reencrypt_reencrypt_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReencryptResponse.ProtoReflect.Descriptor instead. +func (*ReencryptResponse) Descriptor() ([]byte, []int) { + return file_internal_reencrypt_reencrypt_proto_rawDescGZIP(), []int{1} +} + +func (x *ReencryptResponse) GetHeader() []byte { + if x != nil { + return x.Header + } + return nil +} + +var File_internal_reencrypt_reencrypt_proto protoreflect.FileDescriptor + +var file_internal_reencrypt_reencrypt_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x72, 0x65, 0x65, 0x6e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x2f, 0x72, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x72, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x22, + 0x4e, 0x0a, 0x10, 0x52, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x6b, 0x65, + 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x6c, 0x64, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x6c, 0x64, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, + 0x2b, 0x0a, 0x11, 0x52, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x32, 0x5b, 0x0a, 0x09, + 0x52, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x0f, 0x52, 0x65, 0x65, + 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x72, + 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x52, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x72, 0x65, 0x65, 0x6e, + 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x52, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x65, 0x69, 0x63, 0x6e, 0x6f, 0x72, 0x64, + 0x69, 0x63, 0x2f, 0x73, 0x64, 0x61, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x72, 0x65, 0x65, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_internal_reencrypt_reencrypt_proto_rawDescOnce sync.Once + file_internal_reencrypt_reencrypt_proto_rawDescData = file_internal_reencrypt_reencrypt_proto_rawDesc +) + +func file_internal_reencrypt_reencrypt_proto_rawDescGZIP() []byte { + file_internal_reencrypt_reencrypt_proto_rawDescOnce.Do(func() { + file_internal_reencrypt_reencrypt_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_reencrypt_reencrypt_proto_rawDescData) + }) + return file_internal_reencrypt_reencrypt_proto_rawDescData +} + +var file_internal_reencrypt_reencrypt_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_internal_reencrypt_reencrypt_proto_goTypes = []interface{}{ + (*ReencryptRequest)(nil), // 0: reencrypt.ReencryptRequest + (*ReencryptResponse)(nil), // 1: reencrypt.ReencryptResponse +} +var file_internal_reencrypt_reencrypt_proto_depIdxs = []int32{ + 0, // 0: reencrypt.Reencrypt.ReencryptHeader:input_type -> reencrypt.ReencryptRequest + 1, // 1: reencrypt.Reencrypt.ReencryptHeader:output_type -> reencrypt.ReencryptResponse + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_internal_reencrypt_reencrypt_proto_init() } +func file_internal_reencrypt_reencrypt_proto_init() { + if File_internal_reencrypt_reencrypt_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_internal_reencrypt_reencrypt_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReencryptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_internal_reencrypt_reencrypt_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReencryptResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_internal_reencrypt_reencrypt_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_internal_reencrypt_reencrypt_proto_goTypes, + DependencyIndexes: file_internal_reencrypt_reencrypt_proto_depIdxs, + MessageInfos: file_internal_reencrypt_reencrypt_proto_msgTypes, + }.Build() + File_internal_reencrypt_reencrypt_proto = out.File + file_internal_reencrypt_reencrypt_proto_rawDesc = nil + file_internal_reencrypt_reencrypt_proto_goTypes = nil + file_internal_reencrypt_reencrypt_proto_depIdxs = nil +} diff --git a/internal/reencrypt/reencrypt.proto b/internal/reencrypt/reencrypt.proto new file mode 100644 index 0000000..8333725 --- /dev/null +++ b/internal/reencrypt/reencrypt.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +option go_package = "github.com/neicnordic/sda-download/internal/reencrypt"; + +package reencrypt; + +// The Reencrypt service definition. +service Reencrypt { + // Sends the re-encrypted Crypt4gh header + rpc ReencryptHeader (ReencryptRequest) returns (ReencryptResponse) {} +} + +// The request message containing the publickey and old header +message ReencryptRequest { + string publickey = 1; + bytes oldheader = 2; +} + +// The response message containing the re-encrypted header +message ReencryptResponse { + bytes header = 1; +} diff --git a/internal/reencrypt/reencrypt_grpc.pb.go b/internal/reencrypt/reencrypt_grpc.pb.go new file mode 100644 index 0000000..b7d5248 --- /dev/null +++ b/internal/reencrypt/reencrypt_grpc.pb.go @@ -0,0 +1,107 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: internal/reencrypt/reencrypt.proto + +package reencrypt + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ReencryptClient is the client API for Reencrypt service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ReencryptClient interface { + // Sends the re-encrypted Crypt4gh header + ReencryptHeader(ctx context.Context, in *ReencryptRequest, opts ...grpc.CallOption) (*ReencryptResponse, error) +} + +type reencryptClient struct { + cc grpc.ClientConnInterface +} + +func NewReencryptClient(cc grpc.ClientConnInterface) ReencryptClient { + return &reencryptClient{cc} +} + +func (c *reencryptClient) ReencryptHeader(ctx context.Context, in *ReencryptRequest, opts ...grpc.CallOption) (*ReencryptResponse, error) { + out := new(ReencryptResponse) + err := c.cc.Invoke(ctx, "/reencrypt.Reencrypt/ReencryptHeader", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ReencryptServer is the server API for Reencrypt service. +// All implementations must embed UnimplementedReencryptServer +// for forward compatibility +type ReencryptServer interface { + // Sends the re-encrypted Crypt4gh header + ReencryptHeader(context.Context, *ReencryptRequest) (*ReencryptResponse, error) + mustEmbedUnimplementedReencryptServer() +} + +// UnimplementedReencryptServer must be embedded to have forward compatible implementations. +type UnimplementedReencryptServer struct { +} + +func (UnimplementedReencryptServer) ReencryptHeader(context.Context, *ReencryptRequest) (*ReencryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReencryptHeader not implemented") +} +func (UnimplementedReencryptServer) mustEmbedUnimplementedReencryptServer() {} + +// UnsafeReencryptServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ReencryptServer will +// result in compilation errors. +type UnsafeReencryptServer interface { + mustEmbedUnimplementedReencryptServer() +} + +func RegisterReencryptServer(s grpc.ServiceRegistrar, srv ReencryptServer) { + s.RegisterService(&Reencrypt_ServiceDesc, srv) +} + +func _Reencrypt_ReencryptHeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReencryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ReencryptServer).ReencryptHeader(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/reencrypt.Reencrypt/ReencryptHeader", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ReencryptServer).ReencryptHeader(ctx, req.(*ReencryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Reencrypt_ServiceDesc is the grpc.ServiceDesc for Reencrypt service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Reencrypt_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "reencrypt.Reencrypt", + HandlerType: (*ReencryptServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ReencryptHeader", + Handler: _Reencrypt_ReencryptHeader_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "internal/reencrypt/reencrypt.proto", +}