From b8b8e05c833dfb4c4191c8c1391e02d07e0e744f Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sat, 18 Mar 2023 13:20:27 +0100 Subject: renaming files and moving around --- snapshot.go | 163 ------------------------------------------------------------ 1 file changed, 163 deletions(-) delete mode 100644 snapshot.go (limited to 'snapshot.go') diff --git a/snapshot.go b/snapshot.go deleted file mode 100644 index 5a9c50e..0000000 --- a/snapshot.go +++ /dev/null @@ -1,163 +0,0 @@ -package main - -import ( - "bytes" - "context" - "crypto/sha256" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - logger "log" - "net/http" - "os" - "time" - - "git.cs.kau.se/rasmoste/ct-sans/internal/merkle" - ct "github.com/google/certificate-transparency-go" - "github.com/google/certificate-transparency-go/client" - "github.com/google/certificate-transparency-go/jsonclient" - "gitlab.torproject.org/rgdd/ct/pkg/metadata" -) - -func snapshot(opts options) error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - if err := os.MkdirAll(opts.Directory, os.ModePerm); err != nil { - return err - } - - logger.Printf("INFO: updating metadata file\n") - source := metadata.NewHTTPSource(metadata.HTTPSourceOptions{Name: "google"}) - msg, sig, md, err := source.Load(ctx) - if err != nil { - return err - } - if err := os.WriteFile(fmt.Sprintf("%s/%s", opts.Directory, opts.metadataFile), msg, 0644); err != nil { - return err - } - if err := os.WriteFile(fmt.Sprintf("%s/%s", opts.Directory, opts.metadataSignatureFile), sig, 0644); err != nil { - return err - } - timestamp := []byte(fmt.Sprintf("%d", time.Now().Unix())) - if err := os.WriteFile(fmt.Sprintf("%s/%s", opts.Directory, opts.metadataTimestampFile), timestamp, 0644); err != nil { - return err - } - - logger.Printf("INFO: updating signed tree heads\n") - for _, log := range logs(md) { - id, _ := log.Key.ID() - der, _ := x509.MarshalPKIXPublicKey(log.Key) - dir := fmt.Sprintf("%s/%x", opts.logDirectory, id) - sthFile := fmt.Sprintf("%s/%s", dir, opts.sthFile) - if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return fmt.Errorf("%s: %v", log.Description, err) - } - - // Fetch next STH - cli, err := client.New(string(log.URL), &http.Client{}, jsonclient.Options{PublicKeyDER: der, UserAgent: opts.HTTPAgent}) - if err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - nextSTH, err := cli.GetSTH(ctx) - if err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - nextSTHBytes, err := json.Marshal(nextSTH) - if err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - // - // It's a bit ugly that ct.SignedTreeHead contains fields that - // are not populated. Doesn't cause any prolems here, however. - // - - // Bootstrap log if we don't have any STH yet - if _, err := os.Stat(sthFile); err != nil { - if !errors.Is(err, os.ErrNotExist) { - return fmt.Errorf("%s: %v", *log.Description, err) - } - if err := os.WriteFile(sthFile, nextSTHBytes, 0644); err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - - logger.Printf("INFO: bootstrapped %s at tree size %d\n", *log.Description, nextSTH.TreeSize) - continue - } - - // Otherwise: update an existing STH - currSTHBytes, err := os.ReadFile(sthFile) - if err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - var currSTH ct.SignedTreeHead - if err := json.Unmarshal(currSTHBytes, &currSTH); err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - if nextSTH.TreeSize < currSTH.TreeSize { - return fmt.Errorf("%s: next tree size is smaller: %s", *log.Description, nextSTHBytes) - } - if nextSTH.TreeSize == currSTH.TreeSize { - if !bytes.Equal(nextSTH.SHA256RootHash[:], currSTH.SHA256RootHash[:]) { - return fmt.Errorf("%s: split-view: %s", *log.Description, nextSTHBytes) - } - - logger.Printf("INFO: %s is already up-to-date at size %d\n", *log.Description, nextSTH.TreeSize) - continue - } - hashes, err := cli.GetSTHConsistency(ctx, currSTH.TreeSize, nextSTH.TreeSize) - if err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - if err := merkle.VerifyConsistency(currSTH.TreeSize, - nextSTH.TreeSize, - [sha256.Size]byte(currSTH.SHA256RootHash), - [sha256.Size]byte(nextSTH.SHA256RootHash), - proof(hashes)); err != nil { - return fmt.Errorf("%s: inconsistent tree: %v", *log.Description, err) - } - if err := os.WriteFile(sthFile, nextSTHBytes, 0644); err != nil { - return fmt.Errorf("%s: %v", *log.Description, err) - } - logger.Printf("INFO: updated %s to tree size %d\n", *log.Description, nextSTH.TreeSize) - } - return nil -} - -// logs select logs that count towards CT-compliance checks. Logs that don't -// have a description are skipped after printing a warning. -func logs(md metadata.Metadata) (logs []metadata.Log) { - for _, operators := range md.Operators { - for _, log := range operators.Logs { - if log.Description == nil { - fmt.Fprintf(os.Stderr, "WARNING: skipping log without description") - continue - } - if log.State == nil { - continue // skip logs with unknown states - } - if log.State.Name == metadata.LogStatePending { - continue // pending logs do not count towards CT-compliance - } - if log.State.Name == metadata.LogStateRetired { - continue // retired logs are not necessarily reachable - } - if log.State.Name == metadata.LogStateRejected { - continue // rejected logs do not count towards CT-compliance - } - - logs = append(logs, log) - } - } - return -} - -// proof formats hashes so that they can be passed to the merkle package -func proof(hashes [][]byte) (p [][sha256.Size]byte) { - for _, hash := range hashes { - var h [sha256.Size]byte - copy(h[:], hash) - p = append(p, h) - } - return -} -- cgit v1.2.3