Skip to content
Snippets Groups Projects
Unverified Commit 4b1a17c4 authored by priyawadhwa's avatar priyawadhwa Committed by GitHub
Browse files

Update trillian dependency (#281)


* Update trillian dependency to master

This removes calls to the trillian verifier and replaces them with calls to a new rekor verify package!
The `verify` package currently only verifies the signed log root.

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Fix lint

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Add verifier back in and update trillian images

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Make verify private

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Address code review comments

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Roll back to trillian v1.3.13

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>

* Pin trillian to latest commit

Signed-off-by: default avatarPriya Wadhwa <priyawadhwa@google.com>
parent 549b3d79
No related branches found
No related tags found
No related merge requests found
...@@ -17,9 +17,7 @@ package app ...@@ -17,9 +17,7 @@ package app
import ( import (
"bytes" "bytes"
"crypto"
"crypto/x509" "crypto/x509"
"encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"errors" "errors"
...@@ -27,9 +25,6 @@ import ( ...@@ -27,9 +25,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/google/trillian"
tclient "github.com/google/trillian/client"
tcrypto "github.com/google/trillian/crypto"
"github.com/google/trillian/merkle/logverifier" "github.com/google/trillian/merkle/logverifier"
rfc6962 "github.com/google/trillian/merkle/rfc6962/hasher" rfc6962 "github.com/google/trillian/merkle/rfc6962/hasher"
"github.com/spf13/cobra" "github.com/spf13/cobra"
...@@ -39,6 +34,7 @@ import ( ...@@ -39,6 +34,7 @@ import (
"github.com/sigstore/rekor/cmd/rekor-cli/app/state" "github.com/sigstore/rekor/cmd/rekor-cli/app/state"
"github.com/sigstore/rekor/pkg/generated/client/tlog" "github.com/sigstore/rekor/pkg/generated/client/tlog"
"github.com/sigstore/rekor/pkg/log" "github.com/sigstore/rekor/pkg/log"
"github.com/sigstore/rekor/pkg/verify"
) )
type logInfoCmdOutput struct { type logInfoCmdOutput struct {
...@@ -76,24 +72,14 @@ var logInfoCmd = &cobra.Command{ ...@@ -76,24 +72,14 @@ var logInfoCmd = &cobra.Command{
logInfo := result.GetPayload() logInfo := result.GetPayload()
keyHint, err := base64.StdEncoding.DecodeString(logInfo.SignedTreeHead.KeyHint.String()) logRoot := *logInfo.SignedTreeHead.LogRoot
if err != nil { if logRoot == nil {
return nil, err return nil, errors.New("logroot should not be nil")
} }
logRoot, err := base64.StdEncoding.DecodeString(logInfo.SignedTreeHead.LogRoot.String()) signature := *logInfo.SignedTreeHead.Signature
if err != nil { if signature == nil {
return nil, err return nil, errors.New("signature should not be nil")
} }
signature, err := base64.StdEncoding.DecodeString(logInfo.SignedTreeHead.Signature.String())
if err != nil {
return nil, err
}
sth := trillian.SignedLogRoot{
KeyHint: keyHint,
LogRoot: logRoot,
LogRootSignature: signature,
}
publicKey := viper.GetString("rekor_server_public_key") publicKey := viper.GetString("rekor_server_public_key")
if publicKey == "" { if publicKey == "" {
// fetch key from server // fetch key from server
...@@ -114,8 +100,7 @@ var logInfoCmd = &cobra.Command{ ...@@ -114,8 +100,7 @@ var logInfoCmd = &cobra.Command{
return nil, err return nil, err
} }
verifier := tclient.NewLogVerifier(rfc6962.DefaultHasher, pub, crypto.SHA256) lr, err := verify.SignedLogRoot(pub, logRoot, signature)
lr, err := tcrypto.VerifySignedLogRoot(verifier.PubKey, verifier.SigHash, &sth)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -19,10 +19,8 @@ import ( ...@@ -19,10 +19,8 @@ import (
"context" "context"
"crypto" "crypto"
"crypto/x509" "crypto/x509"
"encoding/base64"
"encoding/json" "encoding/json"
"encoding/pem" "encoding/pem"
"errors"
"flag" "flag"
"fmt" "fmt"
"os" "os"
...@@ -31,17 +29,17 @@ import ( ...@@ -31,17 +29,17 @@ import (
_ "gocloud.dev/blob/fileblob" // fileblob _ "gocloud.dev/blob/fileblob" // fileblob
_ "gocloud.dev/blob/gcsblob" _ "gocloud.dev/blob/gcsblob"
"github.com/google/trillian"
tclient "github.com/google/trillian/client"
"github.com/google/trillian/merkle/rfc6962/hasher"
"github.com/google/trillian/types" "github.com/google/trillian/types"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"gocloud.dev/blob" "gocloud.dev/blob"
"github.com/sigstore/rekor/cmd/rekor-cli/app" "github.com/sigstore/rekor/cmd/rekor-cli/app"
"github.com/sigstore/rekor/pkg/generated/client" "github.com/sigstore/rekor/pkg/generated/client"
"github.com/sigstore/rekor/pkg/generated/models"
"github.com/sigstore/rekor/pkg/log" "github.com/sigstore/rekor/pkg/log"
"github.com/sigstore/rekor/pkg/verify"
) )
const rekorSthBucketEnv = "REKOR_STH_BUCKET" const rekorSthBucketEnv = "REKOR_STH_BUCKET"
...@@ -90,7 +88,6 @@ var watchCmd = &cobra.Command{ ...@@ -90,7 +88,6 @@ var watchCmd = &cobra.Command{
return err return err
} }
verifier := tclient.NewLogVerifier(hasher.DefaultHasher, pub, crypto.SHA256)
ctx := context.Background() ctx := context.Background()
bucketURL := os.Getenv(rekorSthBucketEnv) bucketURL := os.Getenv(rekorSthBucketEnv)
if bucketURL == "" { if bucketURL == "" {
...@@ -107,7 +104,7 @@ var watchCmd = &cobra.Command{ ...@@ -107,7 +104,7 @@ var watchCmd = &cobra.Command{
for { for {
<-tick.C <-tick.C
log.Logger.Info("performing check") log.Logger.Info("performing check")
lr, err := doCheck(c, verifier) lr, err := doCheck(c, pub)
if err != nil { if err != nil {
log.Logger.Warnf("error verifiying tree: %s", err) log.Logger.Warnf("error verifiying tree: %s", err)
continue continue
...@@ -134,36 +131,28 @@ func init() { ...@@ -134,36 +131,28 @@ func init() {
rootCmd.AddCommand(watchCmd) rootCmd.AddCommand(watchCmd)
} }
func doCheck(c *client.Rekor, v *tclient.LogVerifier) (*SignedAndUnsignedLogRoot, error) { func doCheck(c *client.Rekor, pub crypto.PublicKey) (*SignedAndUnsignedLogRoot, error) {
li, err := c.Tlog.GetLogInfo(nil) li, err := c.Tlog.GetLogInfo(nil)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrap(err, "getting log info")
} }
keyHint, err := base64.StdEncoding.DecodeString(li.Payload.SignedTreeHead.KeyHint.String()) logRoot := *li.Payload.SignedTreeHead.LogRoot
if err != nil { if logRoot == nil {
return nil, err return nil, errors.New("logroot should not be nil")
} }
logRoot, err := base64.StdEncoding.DecodeString(li.Payload.SignedTreeHead.LogRoot.String()) signature := *li.Payload.SignedTreeHead.Signature
if err != nil { if signature == nil {
return nil, err return nil, errors.New("signature should not be nil")
} }
signature, err := base64.StdEncoding.DecodeString(li.Payload.SignedTreeHead.Signature.String())
verifiedLogRoot, err := verify.SignedLogRoot(pub, logRoot, signature)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrap(err, "signing log root")
}
sth := trillian.SignedLogRoot{
KeyHint: keyHint,
LogRoot: logRoot,
LogRootSignature: signature,
} }
lr := &types.LogRootV1{}
if err := lr.UnmarshalBinary(sth.LogRoot); err != nil {
return nil, err
}
return &SignedAndUnsignedLogRoot{ return &SignedAndUnsignedLogRoot{
SignedLogRoot: &sth, SignedLogRoot: li.GetPayload().SignedTreeHead,
VerifiedLogRoot: lr, VerifiedLogRoot: verifiedLogRoot,
}, nil }, nil
} }
...@@ -187,6 +176,6 @@ func uploadToBlobStorage(ctx context.Context, bucket *blob.Bucket, lr *SignedAnd ...@@ -187,6 +176,6 @@ func uploadToBlobStorage(ctx context.Context, bucket *blob.Bucket, lr *SignedAnd
// For JSON marshalling // For JSON marshalling
type SignedAndUnsignedLogRoot struct { type SignedAndUnsignedLogRoot struct {
SignedLogRoot *trillian.SignedLogRoot SignedLogRoot *models.LogInfoSignedTreeHead
VerifiedLogRoot *types.LogRootV1 VerifiedLogRoot *types.LogRootV1
} }
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
version: '3.4' version: '3.4'
services: services:
mysql: mysql:
image: gcr.io/trillian-opensource-ci/db_server:v1.3.13 image: gcr.io/trillian-opensource-ci/db_server:5e12fb368c8fd19e10aeb5a5cf785107f8069c08
environment: environment:
- MYSQL_ROOT_PASSWORD=zaphod - MYSQL_ROOT_PASSWORD=zaphod
- MYSQL_DATABASE=test - MYSQL_DATABASE=test
...@@ -45,7 +45,7 @@ services: ...@@ -45,7 +45,7 @@ services:
retries: 3 retries: 3
start_period: 5s start_period: 5s
trillian-log-server: trillian-log-server:
image: gcr.io/trillian-opensource-ci/log_server:v1.3.13 image: gcr.io/trillian-opensource-ci/log_server:5e12fb368c8fd19e10aeb5a5cf785107f8069c08
command: [ command: [
"--storage_system=mysql", "--storage_system=mysql",
"--mysql_uri=test:zaphod@tcp(mysql:3306)/test", "--mysql_uri=test:zaphod@tcp(mysql:3306)/test",
...@@ -60,7 +60,7 @@ services: ...@@ -60,7 +60,7 @@ services:
depends_on: depends_on:
- mysql - mysql
trillian-log-signer: trillian-log-signer:
image: gcr.io/trillian-opensource-ci/log_signer:v1.3.13 image: gcr.io/trillian-opensource-ci/log_signer:5e12fb368c8fd19e10aeb5a5cf785107f8069c08
command: [ command: [
"--storage_system=mysql", "--storage_system=mysql",
"--mysql_uri=test:zaphod@tcp(mysql:3306)/test", "--mysql_uri=test:zaphod@tcp(mysql:3306)/test",
......
...@@ -16,7 +16,7 @@ require ( ...@@ -16,7 +16,7 @@ require (
github.com/go-openapi/swag v0.19.15 github.com/go-openapi/swag v0.19.15
github.com/go-openapi/validate v0.20.2 github.com/go-openapi/validate v0.20.2
github.com/google/rpmpack v0.0.0-20210107155803-d6befbf05148 github.com/google/rpmpack v0.0.0-20210107155803-d6befbf05148
github.com/google/trillian v1.3.13 github.com/google/trillian v1.3.14-0.20210413093047-5e12fb368c8f
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c // indirect github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c // indirect
github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7 github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7
github.com/mediocregopher/radix/v4 v4.0.0-beta.1 github.com/mediocregopher/radix/v4 v4.0.0-beta.1
......
This diff is collapsed.
...@@ -46,7 +46,6 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder { ...@@ -46,7 +46,6 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder {
hashString := hex.EncodeToString(root.RootHash) hashString := hex.EncodeToString(root.RootHash)
treeSize := int64(root.TreeSize) treeSize := int64(root.TreeSize)
keyHint := strfmt.Base64(result.SignedLogRoot.GetKeyHint())
logRoot := strfmt.Base64(result.SignedLogRoot.GetLogRoot()) logRoot := strfmt.Base64(result.SignedLogRoot.GetLogRoot())
// sign the log root ourselves to get the log root signature // sign the log root ourselves to get the log root signature
...@@ -58,7 +57,6 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder { ...@@ -58,7 +57,6 @@ func GetLogInfoHandler(params tlog.GetLogInfoParams) middleware.Responder {
signature := strfmt.Base64(sig) signature := strfmt.Base64(sig)
sth := models.LogInfoSignedTreeHead{ sth := models.LogInfoSignedTreeHead{
KeyHint: &keyHint,
LogRoot: &logRoot, LogRoot: &logRoot,
Signature: &signature, Signature: &signature,
} }
......
...@@ -21,7 +21,8 @@ import ( ...@@ -21,7 +21,8 @@ import (
"fmt" "fmt"
"time" "time"
_ "github.com/google/trillian/merkle/rfc6962" // register hasher "github.com/google/trillian/merkle/logverifier"
"github.com/google/trillian/merkle/rfc6962/hasher"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
...@@ -216,7 +217,8 @@ func (t *TrillianClient) getLeafAndProofByIndex(index int64) *Response { ...@@ -216,7 +217,8 @@ func (t *TrillianClient) getLeafAndProofByIndex(index int64) *Response {
}) })
if resp != nil && resp.Proof != nil { if resp != nil && resp.Proof != nil {
if err := t.verifier.VerifyInclusionAtIndex(&root, resp.Leaf.LeafValue, index, resp.Proof.Hashes); err != nil { logVerifier := logverifier.New(hasher.DefaultHasher)
if err := logVerifier.VerifyInclusionProof(index, int64(root.TreeSize), resp.Proof.Hashes, root.RootHash, resp.GetLeaf().MerkleLeafHash); err != nil {
return &Response{ return &Response{
status: status.Code(err), status: status.Code(err),
err: err, err: err,
...@@ -322,7 +324,6 @@ func createAndInitTree(ctx context.Context, adminClient trillian.TrillianAdminCl ...@@ -322,7 +324,6 @@ func createAndInitTree(ctx context.Context, adminClient trillian.TrillianAdminCl
t, err := adminClient.CreateTree(ctx, &trillian.CreateTreeRequest{ t, err := adminClient.CreateTree(ctx, &trillian.CreateTreeRequest{
Tree: &trillian.Tree{ Tree: &trillian.Tree{
TreeType: trillian.TreeType_LOG, TreeType: trillian.TreeType_LOG,
HashStrategy: trillian.HashStrategy_RFC6962_SHA256,
HashAlgorithm: sigpb.DigitallySigned_SHA256, HashAlgorithm: sigpb.DigitallySigned_SHA256,
SignatureAlgorithm: sigpb.DigitallySigned_ECDSA, SignatureAlgorithm: sigpb.DigitallySigned_ECDSA,
TreeState: trillian.TreeState_ACTIVE, TreeState: trillian.TreeState_ACTIVE,
......
//
// Copyright 2021 The Sigstore Authors.
//
// 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 verify
import (
"crypto"
"crypto/ecdsa"
"fmt"
"github.com/google/trillian/types"
"github.com/pkg/errors"
)
// this verification copied from https://github.com/google/trillian/blob/v1.3.13/crypto/verifier.go
// which has since been deleted
// SignedLogRoot verifies the signed log root and returns its contents
func SignedLogRoot(pub crypto.PublicKey, logRoot, logRootSignature []byte) (*types.LogRootV1, error) {
hash := crypto.SHA256
if err := verify(pub, hash, logRoot, logRootSignature); err != nil {
return nil, err
}
var lr types.LogRootV1
if err := lr.UnmarshalBinary(logRoot); err != nil {
return nil, err
}
return &lr, nil
}
// verify cryptographically verifies the output of Signer.
func verify(pub crypto.PublicKey, hasher crypto.Hash, data, sig []byte) error {
if sig == nil {
return errors.New("signature is nil")
}
h := hasher.New()
if _, err := h.Write(data); err != nil {
return errors.Wrap(err, "write")
}
digest := h.Sum(nil)
switch pub := pub.(type) {
case *ecdsa.PublicKey:
if !ecdsa.VerifyASN1(pub, digest, sig) {
return errors.New("verification failed")
}
default:
return fmt.Errorf("unknown public key type: %T", pub)
}
return nil
}
//
// Copyright 2021 The Sigstore Authors.
//
// 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 verify
import (
"context"
"crypto"
"testing"
"github.com/sigstore/rekor/pkg/signer"
)
func TestVerify(t *testing.T) {
signer, err := signer.NewMemory()
if err != nil {
t.Fatalf("getting signer: %v", signer)
}
// sign and verify
ctx := context.Background()
msg := []byte("foo")
signature, _, err := signer.Sign(ctx, msg)
if err != nil {
t.Fatalf("signing: %v", err)
}
// get public key
pubKey, err := signer.PublicKey(ctx)
if err != nil {
t.Fatalf("getting public key: %v", err)
}
// verify should work with correct signature
if err := verify(pubKey, crypto.SHA256, msg, signature); err != nil {
t.Fatalf("error verifying: %v", err)
}
// and fail with an incorrect signature
if err := verify(pubKey, crypto.SHA256, msg, []byte("nope")); err == nil {
t.Fatalf("expected failure with incorrect signature")
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment