...

Source file src/github.com/theupdateframework/go-tuf/client/testdata/go-tuf-transition-M4/generate.go

Documentation: github.com/theupdateframework/go-tuf/client/testdata/go-tuf-transition-M4

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"time"
    11  
    12  	tuf "github.com/theupdateframework/go-tuf"
    13  	"github.com/theupdateframework/go-tuf/data"
    14  	"github.com/theupdateframework/go-tuf/pkg/keys"
    15  )
    16  
    17  var expirationDate = time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC)
    18  
    19  type persistedKeys struct {
    20  	Encrypted bool               `json:"encrypted"`
    21  	Data      []*data.PrivateKey `json:"data"`
    22  }
    23  
    24  func assertNoError(err error) {
    25  	if err != nil {
    26  		panic(fmt.Sprintf("assertion failed: %s", err))
    27  	}
    28  }
    29  
    30  func copyRepo(src string, dst string) {
    31  	cmd := exec.Command("cp", "-r", src, dst)
    32  	assertNoError(cmd.Run())
    33  }
    34  
    35  func newRepo(dir string) *tuf.Repo {
    36  	repo, err := tuf.NewRepoIndent(tuf.FileSystemStore(dir, nil), "", "\t")
    37  	assertNoError(err)
    38  
    39  	return repo
    40  }
    41  
    42  func commit(dir string, repo *tuf.Repo) {
    43  	assertNoError(repo.SnapshotWithExpires(expirationDate))
    44  	assertNoError(repo.TimestampWithExpires(expirationDate))
    45  	assertNoError(repo.Commit())
    46  
    47  	// Remove the keys directory to make sure we don't accidentally use a key.
    48  	assertNoError(os.RemoveAll(filepath.Join(dir, "keys")))
    49  }
    50  
    51  func addKeys(repo *tuf.Repo, roleKeys map[string][]*data.PrivateKey) {
    52  	for role, keys := range roleKeys {
    53  		for _, key := range keys {
    54  			assertNoError(repo.AddPrivateKeyWithExpires(role, key, expirationDate))
    55  		}
    56  	}
    57  }
    58  
    59  func addTargets(repo *tuf.Repo, dir string, files map[string][]byte) {
    60  	paths := []string{}
    61  	for file, data := range files {
    62  		path := filepath.Join(dir, "staged", "targets", file)
    63  		assertNoError(os.MkdirAll(filepath.Dir(path), 0755))
    64  		assertNoError(os.WriteFile(path, data, 0644))
    65  		paths = append(paths, file)
    66  	}
    67  	assertNoError(repo.AddTargetsWithExpires(paths, nil, expirationDate))
    68  }
    69  
    70  func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
    71  	for _, key := range keyList {
    72  		signer, err := keys.GetSigner(key)
    73  		assertNoError(err)
    74  		assertNoError(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
    75  	}
    76  }
    77  
    78  func generateRepos(dir string, consistentSnapshot bool) {
    79  	f, err := os.Open("../keys.json")
    80  	assertNoError(err)
    81  
    82  	var roleKeys map[string][][]*data.PrivateKey
    83  	assertNoError(json.NewDecoder(f).Decode(&roleKeys))
    84  
    85  	// Collect all the initial keys we'll use when creating repositories.
    86  	// We'll modify this to reflect rotated keys.
    87  	keys := map[string][]*data.PrivateKey{
    88  		"root":      roleKeys["root"][0],
    89  		"targets":   roleKeys["targets"][0],
    90  		"snapshot":  roleKeys["snapshot"][0],
    91  		"timestamp": roleKeys["timestamp"][0],
    92  	}
    93  
    94  	// Create the initial repo.
    95  	dir0 := filepath.Join(dir, "0")
    96  	repo0 := newRepo(dir0)
    97  	repo0.Init(consistentSnapshot)
    98  	addKeys(repo0, keys)
    99  	addTargets(repo0, dir0, map[string][]byte{"0": []byte("0")})
   100  	commit(dir0, repo0)
   101  
   102  	// Rotate all the keys to make sure that works.
   103  	oldDir := dir0
   104  	i := 1
   105  	for _, role := range []string{"root", "targets", "snapshot", "timestamp"} {
   106  		// Setup the repo.
   107  		stepName := fmt.Sprintf("%d", i)
   108  		d := filepath.Join(dir, stepName)
   109  		copyRepo(oldDir, d)
   110  		repo := newRepo(d)
   111  		addKeys(repo, keys)
   112  
   113  		// Actually rotate the keys
   114  		revokeKeys(repo, role, roleKeys[role][0])
   115  		addKeys(repo, map[string][]*data.PrivateKey{
   116  			role: roleKeys[role][1],
   117  		})
   118  		keys[role] = roleKeys[role][1]
   119  
   120  		// Add a target to make sure that works, then commit.
   121  		addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
   122  		commit(d, repo)
   123  
   124  		i += 1
   125  		oldDir = d
   126  	}
   127  
   128  	// Add another target file to make sure the workflow worked.
   129  	stepName := fmt.Sprintf("%d", i)
   130  	d := filepath.Join(dir, stepName)
   131  	copyRepo(oldDir, d)
   132  	repo := newRepo(d)
   133  	addKeys(repo, keys)
   134  	addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
   135  	commit(d, repo)
   136  }
   137  
   138  func main() {
   139  	cwd, err := os.Getwd()
   140  	assertNoError(err)
   141  
   142  	for _, consistentSnapshot := range []bool{false, true} {
   143  		name := fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot)
   144  		log.Printf("generating %s", name)
   145  		generateRepos(filepath.Join(cwd, name), consistentSnapshot)
   146  	}
   147  
   148  }
   149  

View as plain text