From 33e199c9939e110bd677e7b3e43547c6e55bb6e2 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Mon, 13 Sep 2021 13:26:06 +0200 Subject: fixed {st,stfe,system-transparency} -> sigsum --- cmd/siglog_server/.gitignore | 1 - cmd/siglog_server/README.md | 60 --------------- cmd/siglog_server/main.go | 176 ------------------------------------------ cmd/sigsum_log_go/.gitignore | 1 + cmd/sigsum_log_go/README.md | 57 ++++++++++++++ cmd/sigsum_log_go/main.go | 177 +++++++++++++++++++++++++++++++++++++++++++ cmd/tmp/cosign/main.go | 6 +- cmd/tmp/submit/main.go | 4 +- 8 files changed, 240 insertions(+), 242 deletions(-) delete mode 100644 cmd/siglog_server/.gitignore delete mode 100644 cmd/siglog_server/README.md delete mode 100644 cmd/siglog_server/main.go create mode 100644 cmd/sigsum_log_go/.gitignore create mode 100644 cmd/sigsum_log_go/README.md create mode 100644 cmd/sigsum_log_go/main.go (limited to 'cmd') diff --git a/cmd/siglog_server/.gitignore b/cmd/siglog_server/.gitignore deleted file mode 100644 index 254defd..0000000 --- a/cmd/siglog_server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -server diff --git a/cmd/siglog_server/README.md b/cmd/siglog_server/README.md deleted file mode 100644 index 71bb3ac..0000000 --- a/cmd/siglog_server/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Run Trillian + STFE locally -Trillian uses a database. So, we will need to set that up. It is documented -[here](https://github.com/google/trillian#mysql-setup), and how to check that it -is setup properly -[here](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#data-storage). - -Other than the database we need the Trillian log signer, Trillian log server, -and STFE server. -``` -$ go install github.com/google/trillian/cmd/trillian_log_signer -$ go install github.com/google/trillian/cmd/trillian_log_server -$ go install -``` - -Start Trillian log signer: -``` -trillian_log_signer --logtostderr -v 9 --force_master --rpc_endpoint=localhost:6961 --http_endpoint=localhost:6964 --num_sequencers 1 --sequencer_interval 100ms --batch_size 100 -``` - -Start Trillian log server: -``` -trillian_log_server --logtostderr -v 9 --rpc_endpoint=localhost:6962 --http_endpoint=localhost:6963 -``` - -As described in more detail -[here](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#trillian-services), -we need to provision a Merkle tree once: -``` -$ go install github.com/google/trillian/cmd/createtree -$ createtree --admin_server localhost:6962 - -``` - -Hang on to ``. Our STFE server will use it when talking to the -Trillian log server to specify which Merkle tree we are working against. - -(If you take a look in the `Trees` table you will see that the tree has been -provisioned.) - -We will also need a public key-pair and log identifier for the STFE server. -``` -$ go install github.com/system-transparency/stfe/types/cmd/new-namespace -sk: -vk: -ed25519_v1: -``` - -The log's identifier is `` and contains the public verification key -``. The log's corresponding secret signing key is ``. - -Start STFE server: -``` -$ ./server --logtostderr -v 9 --http_endpoint localhost:6965 --log_rpc_server localhost:6962 --trillian_id --key -``` - -If the log is responsive on, e.g., `GET http://localhost:6965/st/v1/get-latest-sth` you -may want to try running -`github.com/system-transparency/stfe/client/cmd/example.sh`. You need to -configure the log's id though for verification to work (flag `log_id`, which -should be set to the `` output above). diff --git a/cmd/siglog_server/main.go b/cmd/siglog_server/main.go deleted file mode 100644 index 368b0a7..0000000 --- a/cmd/siglog_server/main.go +++ /dev/null @@ -1,176 +0,0 @@ -// Package main provides an STFE server binary -package main - -import ( - "context" - "crypto" - "crypto/ed25519" - "encoding/hex" - "flag" - "fmt" - "net/http" - "os" - "os/signal" - "strings" - "sync" - "syscall" - "time" - - "github.com/golang/glog" - "github.com/google/trillian" - "github.com/prometheus/client_golang/prometheus/promhttp" - stfe "github.com/system-transparency/stfe/pkg/instance" - "github.com/system-transparency/stfe/pkg/state" - trillianWrapper "github.com/system-transparency/stfe/pkg/trillian" - "github.com/system-transparency/stfe/pkg/types" - "google.golang.org/grpc" -) - -var ( - httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients") - rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients") - prefix = flag.String("prefix", "", "a prefix that proceeds /st/v0/") - trillianID = flag.Int64("trillian_id", 0, "log identifier in the Trillian database") - deadline = flag.Duration("deadline", time.Second*10, "deadline for backend requests") - key = flag.String("key", "", "hex-encoded Ed25519 signing key") - witnesses = flag.String("witnesses", "", "comma-separated list of trusted witness verification keys in hex") - maxRange = flag.Int64("max_range", 10, "maximum number of entries that can be retrived in a single request") - interval = flag.Duration("interval", time.Second*30, "interval used to rotate the log's cosigned STH") -) - -func main() { - flag.Parse() - defer glog.Flush() - - // wait for clean-up before exit - var wg sync.WaitGroup - defer wg.Wait() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - glog.V(3).Infof("configuring stfe instance...") - instance, err := setupInstanceFromFlags() - if err != nil { - glog.Errorf("setupInstance: %v", err) - return - } - - glog.V(3).Infof("spawning state manager") - go func() { - wg.Add(1) - defer wg.Done() - instance.Stateman.Run(ctx) - glog.Errorf("state manager shutdown") - cancel() // must have state manager running - }() - - glog.V(3).Infof("spawning await") - server := http.Server{Addr: *httpEndpoint} - go await(ctx, func() { - wg.Add(1) - defer wg.Done() - ctxInner, _ := context.WithTimeout(ctx, time.Second*60) - glog.Infof("Shutting down HTTP server...") - server.Shutdown(ctxInner) - glog.V(3).Infof("HTTP server shutdown") - glog.Infof("Shutting down spawned go routines...") - cancel() - }) - - glog.Infof("Serving on %v/%v", *httpEndpoint, *prefix) - if err = server.ListenAndServe(); err != http.ErrServerClosed { - glog.Errorf("ListenAndServe: %v", err) - } -} - -// SetupInstance sets up a new STFE instance from flags -func setupInstanceFromFlags() (*stfe.Instance, error) { - var i stfe.Instance - var err error - - // Setup log configuration - i.Signer, i.LogID, err = newLogIdentity(*key) - if err != nil { - return nil, fmt.Errorf("newLogIdentity: %v", err) - } - i.TreeID = *trillianID - i.Prefix = *prefix - i.MaxRange = *maxRange - i.Deadline = *deadline - i.Interval = *interval - i.Witnesses, err = newWitnessMap(*witnesses) - if err != nil { - return nil, fmt.Errorf("newWitnessMap: %v", err) - } - - // Setup log client - dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(i.Deadline)} - conn, err := grpc.Dial(*rpcBackend, dialOpts...) - if err != nil { - return nil, fmt.Errorf("Dial: %v", err) - } - i.Client = &trillianWrapper.TrillianClient{ - TreeID: i.TreeID, - GRPC: trillian.NewTrillianLogClient(conn), - } - - // Setup state manager - i.Stateman, err = state.NewStateManagerSingle(i.Client, i.Signer, i.Interval, i.Deadline) - if err != nil { - return nil, fmt.Errorf("NewStateManager: %v", err) - } - - // Register HTTP endpoints - mux := http.NewServeMux() - http.Handle("/", mux) - for _, handler := range i.Handlers() { - glog.V(3).Infof("adding handler: %s", handler.Path()) - mux.Handle(handler.Path(), handler) - } - glog.V(3).Infof("Adding prometheus handler on path: /metrics") - http.Handle("/metrics", promhttp.Handler()) - - return &i, nil -} - -func newLogIdentity(key string) (crypto.Signer, string, error) { - buf, err := hex.DecodeString(key) - if err != nil { - return nil, "", fmt.Errorf("DecodeString: %v", err) - } - sk := crypto.Signer(ed25519.PrivateKey(buf)) - vk := sk.Public().(ed25519.PublicKey) - return sk, hex.EncodeToString([]byte(vk[:])), nil -} - -// newWitnessMap creates a new map of trusted witnesses -func newWitnessMap(witnesses string) (map[[types.HashSize]byte][types.VerificationKeySize]byte, error) { - w := make(map[[types.HashSize]byte][types.VerificationKeySize]byte) - if len(witnesses) > 0 { - for _, witness := range strings.Split(witnesses, ",") { - b, err := hex.DecodeString(witness) - if err != nil { - return nil, fmt.Errorf("DecodeString: %v", err) - } - - var vk [types.VerificationKeySize]byte - if n := copy(vk[:], b); n != types.VerificationKeySize { - return nil, fmt.Errorf("Invalid verification key size: %v", n) - } - w[*types.Hash(vk[:])] = vk - } - } - return w, nil -} - -// await waits for a shutdown signal and then runs a clean-up function -func await(ctx context.Context, done func()) { - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) - select { - case <-sigs: - case <-ctx.Done(): - } - glog.V(3).Info("received shutdown signal") - done() -} diff --git a/cmd/sigsum_log_go/.gitignore b/cmd/sigsum_log_go/.gitignore new file mode 100644 index 0000000..254defd --- /dev/null +++ b/cmd/sigsum_log_go/.gitignore @@ -0,0 +1 @@ +server diff --git a/cmd/sigsum_log_go/README.md b/cmd/sigsum_log_go/README.md new file mode 100644 index 0000000..5e419ba --- /dev/null +++ b/cmd/sigsum_log_go/README.md @@ -0,0 +1,57 @@ +# Run Trillian + sigsum-log-go locally +Trillian uses a database. So, we will need to set that up. It is documented +[here](https://github.com/google/trillian#mysql-setup), and how to check that it +is setup properly +[here](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#data-storage). + +Other than the database we need Trillian log signer, Trillian log server, and +sigsum-log-go. +``` +$ go install github.com/google/trillian/cmd/trillian_log_signer +$ go install github.com/google/trillian/cmd/trillian_log_server +$ go install +``` + +Start Trillian log signer: +``` +trillian_log_signer --logtostderr -v 9 --force_master --rpc_endpoint=localhost:6961 --http_endpoint=localhost:6964 --num_sequencers 1 --sequencer_interval 100ms --batch_size 100 +``` + +Start Trillian log server: +``` +trillian_log_server --logtostderr -v 9 --rpc_endpoint=localhost:6962 --http_endpoint=localhost:6963 +``` + +As described in more detail +[here](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#trillian-services), +we need to provision a Merkle tree once: +``` +$ go install github.com/google/trillian/cmd/createtree +$ createtree --admin_server localhost:6962 + +``` + +Hang on to ``. Our sigsum-log-go instance will use it when talking to +the Trillian log server to specify which Merkle tree we are working against. + +(If you take a look in the `Trees` table you will see that the tree has been +provisioned.) + +We will also need a public key-pair for sigsum-log-go. +``` +$ go install golang.sigsum.org/sigsum-log-go/cmd/tmp/keygen +$ ./keygen +sk: +vk: +``` + +Start sigsum-log-go: +``` +$ tree_id= +$ sk= +$ sigsum_log_go --logtostderr -v 9 --http_endpoint localhost:6965 --log_rpc_server localhost:6962 --trillian_id $tree_id --key $sk +``` + +Quick test: +- curl http://localhost:6965/sigsum/v0/get-tree-head-latest +- try `submit` and `cosign` commands in `cmd/tmp` diff --git a/cmd/sigsum_log_go/main.go b/cmd/sigsum_log_go/main.go new file mode 100644 index 0000000..6189b1d --- /dev/null +++ b/cmd/sigsum_log_go/main.go @@ -0,0 +1,177 @@ +// Package main provides a sigsum-log-go binary +package main + +import ( + "context" + "crypto" + "crypto/ed25519" + "encoding/hex" + "flag" + "fmt" + "net/http" + "os" + "os/signal" + "strings" + "sync" + "syscall" + "time" + + "github.com/golang/glog" + "github.com/google/trillian" + "github.com/prometheus/client_golang/prometheus/promhttp" + "google.golang.org/grpc" + + sigsum "golang.sigsum.org/sigsum-log-go/pkg/instance" + "golang.sigsum.org/sigsum-log-go/pkg/state" + trillianWrapper "golang.sigsum.org/sigsum-log-go/pkg/trillian" + "golang.sigsum.org/sigsum-log-go/pkg/types" +) + +var ( + httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where sigsum-log-go serves clients") + rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients") + prefix = flag.String("prefix", "", "a prefix that proceeds /sigsum/v0/") + trillianID = flag.Int64("trillian_id", 0, "log identifier in the Trillian database") + deadline = flag.Duration("deadline", time.Second*10, "deadline for backend requests") + key = flag.String("key", "", "hex-encoded Ed25519 signing key") + witnesses = flag.String("witnesses", "", "comma-separated list of trusted witness verification keys in hex") + maxRange = flag.Int64("max_range", 10, "maximum number of entries that can be retrived in a single request") + interval = flag.Duration("interval", time.Second*30, "interval used to rotate the log's cosigned STH") +) + +func main() { + flag.Parse() + defer glog.Flush() + + // wait for clean-up before exit + var wg sync.WaitGroup + defer wg.Wait() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + glog.V(3).Infof("configuring sigsum-log-go instance...") + instance, err := setupInstanceFromFlags() + if err != nil { + glog.Errorf("setupInstance: %v", err) + return + } + + glog.V(3).Infof("spawning state manager") + go func() { + wg.Add(1) + defer wg.Done() + instance.Stateman.Run(ctx) + glog.Errorf("state manager shutdown") + cancel() // must have state manager running + }() + + glog.V(3).Infof("spawning await") + server := http.Server{Addr: *httpEndpoint} + go await(ctx, func() { + wg.Add(1) + defer wg.Done() + ctxInner, _ := context.WithTimeout(ctx, time.Second*60) + glog.Infof("Shutting down HTTP server...") + server.Shutdown(ctxInner) + glog.V(3).Infof("HTTP server shutdown") + glog.Infof("Shutting down spawned go routines...") + cancel() + }) + + glog.Infof("Serving on %v/%v", *httpEndpoint, *prefix) + if err = server.ListenAndServe(); err != http.ErrServerClosed { + glog.Errorf("ListenAndServe: %v", err) + } +} + +// SetupInstance sets up a new sigsum-log-go instance from flags +func setupInstanceFromFlags() (*sigsum.Instance, error) { + var i sigsum.Instance + var err error + + // Setup log configuration + i.Signer, i.LogID, err = newLogIdentity(*key) + if err != nil { + return nil, fmt.Errorf("newLogIdentity: %v", err) + } + i.TreeID = *trillianID + i.Prefix = *prefix + i.MaxRange = *maxRange + i.Deadline = *deadline + i.Interval = *interval + i.Witnesses, err = newWitnessMap(*witnesses) + if err != nil { + return nil, fmt.Errorf("newWitnessMap: %v", err) + } + + // Setup log client + dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(i.Deadline)} + conn, err := grpc.Dial(*rpcBackend, dialOpts...) + if err != nil { + return nil, fmt.Errorf("Dial: %v", err) + } + i.Client = &trillianWrapper.TrillianClient{ + TreeID: i.TreeID, + GRPC: trillian.NewTrillianLogClient(conn), + } + + // Setup state manager + i.Stateman, err = state.NewStateManagerSingle(i.Client, i.Signer, i.Interval, i.Deadline) + if err != nil { + return nil, fmt.Errorf("NewStateManager: %v", err) + } + + // Register HTTP endpoints + mux := http.NewServeMux() + http.Handle("/", mux) + for _, handler := range i.Handlers() { + glog.V(3).Infof("adding handler: %s", handler.Path()) + mux.Handle(handler.Path(), handler) + } + glog.V(3).Infof("Adding prometheus handler on path: /metrics") + http.Handle("/metrics", promhttp.Handler()) + + return &i, nil +} + +func newLogIdentity(key string) (crypto.Signer, string, error) { + buf, err := hex.DecodeString(key) + if err != nil { + return nil, "", fmt.Errorf("DecodeString: %v", err) + } + sk := crypto.Signer(ed25519.PrivateKey(buf)) + vk := sk.Public().(ed25519.PublicKey) + return sk, hex.EncodeToString([]byte(vk[:])), nil +} + +// newWitnessMap creates a new map of trusted witnesses +func newWitnessMap(witnesses string) (map[[types.HashSize]byte][types.VerificationKeySize]byte, error) { + w := make(map[[types.HashSize]byte][types.VerificationKeySize]byte) + if len(witnesses) > 0 { + for _, witness := range strings.Split(witnesses, ",") { + b, err := hex.DecodeString(witness) + if err != nil { + return nil, fmt.Errorf("DecodeString: %v", err) + } + + var vk [types.VerificationKeySize]byte + if n := copy(vk[:], b); n != types.VerificationKeySize { + return nil, fmt.Errorf("Invalid verification key size: %v", n) + } + w[*types.Hash(vk[:])] = vk + } + } + return w, nil +} + +// await waits for a shutdown signal and then runs a clean-up function +func await(ctx context.Context, done func()) { + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + select { + case <-sigs: + case <-ctx.Done(): + } + glog.V(3).Info("received shutdown signal") + done() +} diff --git a/cmd/tmp/cosign/main.go b/cmd/tmp/cosign/main.go index a51f17d..629e7ac 100644 --- a/cmd/tmp/cosign/main.go +++ b/cmd/tmp/cosign/main.go @@ -9,11 +9,11 @@ import ( "log" "net/http" - "github.com/system-transparency/stfe/pkg/types" + "golang.sigsum.org/sigsum-log-go/pkg/types" ) var ( - url = flag.String("url", "http://localhost:6965/st/v0", "base url") + url = flag.String("url", "http://localhost:6965/sigsum/v0", "base url") sk = flag.String("sk", "e1d7c494dacb0ddf809a17e4528b01f584af22e3766fa740ec52a1711c59500d711090dd2286040b50961b0fe09f58aa665ccee5cb7ee042d819f18f6ab5046b", "hex key") ) @@ -48,7 +48,7 @@ func main() { if err := sigident.MarshalASCII(buf); err != nil { log.Fatalf("MarshalASCII: %v", err) } - rsp, err = http.Post(*url+"/add-cosignature", "type/stfe", buf) + rsp, err = http.Post(*url+"/add-cosignature", "type/sigsum", buf) if err != nil { log.Fatalf("Post: %v", err) } diff --git a/cmd/tmp/submit/main.go b/cmd/tmp/submit/main.go index 3dcaa97..43fd457 100644 --- a/cmd/tmp/submit/main.go +++ b/cmd/tmp/submit/main.go @@ -7,7 +7,7 @@ import ( "crypto/rand" "fmt" - "github.com/system-transparency/stfe/pkg/types" + "golang.sigsum.org/sigsum-log-go/pkg/types" ) func main() { @@ -25,5 +25,5 @@ func main() { sig := ed25519.Sign(sk, msg.Marshal()) //fmt.Printf("sk: %x\nvk: %x\n", sk[:], vk[:]) - fmt.Printf("echo \"shard_hint=%d\nchecksum=%x\nsignature_over_message=%x\nverification_key=%x\ndomain_hint=%s\" | curl --data-binary @- localhost:6965/st/v0/add-leaf\n", msg.ShardHint, msg.Checksum[:], sig, vk[:], "example.com") + fmt.Printf("echo \"shard_hint=%d\nchecksum=%x\nsignature=%x\nverification_key=%x\ndomain_hint=%s\" | curl --data-binary @- localhost:6965/sigsum/v0/add-leaf\n", msg.ShardHint, msg.Checksum[:], sig, vk[:], "example.com") } -- cgit v1.2.3