Permalink
Browse files

Implement delegate server: GetKeySet (#893)

* Implement UserManager.GetKeySet

* sql keyset implementation

* Implement delegate server

* go fmt -s

* Download test dependencies as well

* update years to 2018, nits, and tests

* Fix linter errors

* spell correct
  • Loading branch information...
gdbelvin committed Jan 3, 2018
1 parent 053df4c commit 4db6fe2ff69786aea1a7e0650afab2615a0ee9cc
View
@@ -24,7 +24,7 @@ addons:
install:
- go get -u github.com/alecthomas/gometalinter
- gometalinter --install
- go get ./...
- go get -t ./...
script:
- export TRILLIAN_SQL_DRIVER=mysql
View
@@ -22,7 +22,7 @@
# TODO: Makefile will be deleted once the repo is public. Check issue #411.
main:
go build ./cmd/keytransparency-server ./cmd/keytransparency-sequencer ./cmd/keytransparency-client
go build ./cmd/keytransparency-server ./cmd/keytransparency-sequencer ./cmd/keytransparency-client ./cmd/keytransparency-delegate
mysql:
go build -tags mysql ./cmd/keytransparency-server ./cmd/keytransparency-sequencer ./cmd/keytransparency-client
@@ -0,0 +1,130 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package main is a delegate server that can be used to
// (a) create user accounts.
// (b) update user accounts (that this server has created).
//
// The delegate server is designed to be used by app operators
// to provision and update users before users take control over
// their own key management.
//
// The delegate server may also be used to implement a third party account
// reset provider service, should users wish to trust these providers with the
// ability to control and update their accounts.
package main
import (
"database/sql"
"flag"
"net/http"
"github.com/google/keytransparency/cmd/serverutil"
"github.com/google/keytransparency/core/managementserver"
"github.com/google/keytransparency/impl/sql/engine"
"github.com/google/keytransparency/impl/sql/keysets"
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus/promhttp"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
pb "github.com/google/keytransparency/core/api/usermanager/v1/usermanager_proto"
_ "github.com/google/trillian/crypto/keys/der/proto"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
)
var (
addr = flag.String("addr", ":8080", "The ip:port combination to listen on")
metricsAddr = flag.String("metrics-addr", ":8081", "The ip:port to publish metrics on")
serverDBPath = flag.String("db", "test:zaphod@tcp(localhost:3306)/test", "Database connection string")
keyFile = flag.String("tls-key", "genfiles/server.key", "TLS private key file")
certFile = flag.String("tls-cert", "genfiles/server.crt", "TLS cert file")
instance = flag.Int64("instance", 0, "Instance number. Typically 0.")
)
func openDB() (*sql.DB, error) {
db, err := sql.Open(engine.DriverName, *serverDBPath)
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
return nil, err
}
return db, nil
}
func main() {
flag.Parse()
// Connect to database.
sqldb, err := openDB()
if err != nil {
glog.Exitf("Failed opening database: %v", err)
}
defer sqldb.Close()
keysetdb, err := keysets.New(sqldb)
if err != nil {
glog.Exitf("Failed to create keyset table: %v", err)
}
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
if err != nil {
glog.Exitf("Failed to load server credentials %v", err)
}
// Create gRPC server.
svr := managementserver.New(*instance, keysetdb)
grpcServer := grpc.NewServer(
grpc.Creds(creds),
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
)
pb.RegisterUserManagerServiceServer(grpcServer, svr)
reflection.Register(grpcServer)
grpc_prometheus.Register(grpcServer)
// Create HTTP handlers and gRPC gateway.
tcreds, err := credentials.NewClientTLSFromFile(*certFile, "")
if err != nil {
glog.Exitf("Failed opening cert file %v: %v", *certFile, err)
}
gwmux, err := serverutil.GrpcGatewayMux(*addr, tcreds,
pb.RegisterUserManagerServiceHandlerFromEndpoint)
if err != nil {
glog.Exitf("Failed setting up REST proxy: %v", err)
}
// Insert handlers for other http paths here.
mux := http.NewServeMux()
mux.Handle("/", gwmux)
metricMux := http.NewServeMux()
metricMux.Handle("/metrics", promhttp.Handler())
go func() {
glog.Infof("Hosting metrics on %v", *metricsAddr)
if err := http.ListenAndServe(*metricsAddr, metricMux); err != nil {
glog.Exitf("ListenAndServeTLS(%v): %v", *metricsAddr, err)
}
}()
// Serve HTTP over TLS.
glog.Infof("Listening on %v", *addr)
if err := http.ListenAndServeTLS(*addr, *certFile, *keyFile,
serverutil.GrpcHandlerFunc(grpcServer, mux)); err != nil {
glog.Errorf("ListenAndServeTLS: %v", err)
}
}
View
@@ -0,0 +1,55 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package fake
import (
"context"
tpb "github.com/google/keytransparency/core/api/type/type_proto"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// keyID uniquely identifies a keyset.
type keyID struct {
instance int64
domainID string
appID string
}
// KeySets implements storage.UserManagerTable in memory.
type KeySets struct {
keysets map[keyID]*tpb.KeySet
}
// NewKeySets produces a fake implementation of storage.UserManagerTable.
func NewKeySets() *KeySets {
return &KeySets{
keysets: make(map[keyID]*tpb.KeySet),
}
}
// Get returns the requested keyset.
func (k *KeySets) Get(ctx context.Context, instance int64, domainID, appID string) (*tpb.KeySet, error) {
ks, ok := k.keysets[keyID{
instance: instance,
domainID: domainID,
appID: appID,
}]
if !ok {
return nil, status.Errorf(codes.NotFound, "KeySet %v/%v/%v not found", instance, domainID, appID)
}
return ks, nil
}
@@ -23,20 +23,32 @@ import (
tpb "github.com/google/keytransparency/core/api/type/type_proto"
pb "github.com/google/keytransparency/core/api/usermanager/v1/usermanager_proto"
"github.com/google/keytransparency/core/storage"
)
// Server implements pb.UserManagerServiceServer
type Server struct{}
type Server struct {
instance int64
keysets storage.KeySets
}
// New creates a new managementserver
func New() *Server {
return &Server{}
func New(instance int64, keysets storage.KeySets) *Server {
return &Server{
instance: instance,
keysets: keysets,
}
}
// GetKeySet returns a list of public keys (a keyset) that corresponds to the signing keys
// this service has for a given domain and app.
func (s *Server) GetKeySet(context.Context, *pb.GetKeySetRequest) (*tpb.KeySet, error) {
return nil, status.Errorf(codes.Unimplemented, "unimplemented")
func (s *Server) GetKeySet(ctx context.Context, in *pb.GetKeySetRequest) (*tpb.KeySet, error) {
ks, err := s.keysets.Get(ctx, s.instance, in.GetDomainId(), in.GetAppId())
if err != nil {
return nil, err
}
ks.SigningKeys = nil // DON'T LEAK PRIVATE KEYS!!
return ks, nil
}
// CreateUser creates a new user and initializes it.
View
@@ -0,0 +1,31 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package storage defines storage interfaces.
package storage
import (
"context"
tpb "github.com/google/keytransparency/core/api/type/type_proto"
)
// KeySets gets and sets keysets.
type KeySets interface {
// Get returns the keyset for a given domain and app.
// instance supports hosting multiple usermanager servers on the same infrastructure.
Get(ctx context.Context, instance int64, domainID, appID string) (*tpb.KeySet, error)
// Set saves a keyset.
Set(ctx context.Context, instance int64, domainID, appID string, k *tpb.KeySet) error
}
Oops, something went wrong.

0 comments on commit 4db6fe2

Please sign in to comment.