...

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

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

     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, keyList := range roleKeys {
    53  		for _, key := range keyList {
    54  			signer, err := keys.GetSigner(key)
    55  			assertNoError(err)
    56  			assertNoError(repo.AddPrivateKeyWithExpires(role, signer, expirationDate))
    57  		}
    58  	}
    59  }
    60  
    61  func addTargets(repo *tuf.Repo, dir string, files map[string][]byte) {
    62  	paths := []string{}
    63  	for file, data := range files {
    64  		path := filepath.Join(dir, "staged", "targets", file)
    65  		assertNoError(os.MkdirAll(filepath.Dir(path), 0755))
    66  		assertNoError(os.WriteFile(path, data, 0644))
    67  		paths = append(paths, file)
    68  	}
    69  	assertNoError(repo.AddTargetsWithExpires(paths, nil, expirationDate))
    70  }
    71  
    72  func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
    73  	for _, key := range keyList {
    74  		signer, err := keys.GetSigner(key)
    75  		assertNoError(err)
    76  		assertNoError(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
    77  	}
    78  }
    79  
    80  func generateRepos(dir string, consistentSnapshot bool) {
    81  	f, err := os.Open("../keys.json")
    82  	assertNoError(err)
    83  
    84  	var roleKeys map[string][][]*data.PrivateKey
    85  	assertNoError(json.NewDecoder(f).Decode(&roleKeys))
    86  
    87  	// Collect all the initial keys we'll use when creating repositories.
    88  	// We'll modify this to reflect rotated keys.
    89  	keys := map[string][]*data.PrivateKey{
    90  		"root":      roleKeys["root"][0],
    91  		"targets":   roleKeys["targets"][0],
    92  		"snapshot":  roleKeys["snapshot"][0],
    93  		"timestamp": roleKeys["timestamp"][0],
    94  	}
    95  
    96  	// Create the initial repo.
    97  	dir0 := filepath.Join(dir, "0")
    98  	repo0 := newRepo(dir0)
    99  	repo0.Init(consistentSnapshot)
   100  	addKeys(repo0, keys)
   101  	addTargets(repo0, dir0, map[string][]byte{"0": []byte("0")})
   102  	commit(dir0, repo0)
   103  
   104  	// Rotate all the keys to make sure that works.
   105  	oldDir := dir0
   106  	i := 1
   107  	for _, role := range []string{"root", "targets", "snapshot", "timestamp"} {
   108  		// Setup the repo.
   109  		stepName := fmt.Sprintf("%d", i)
   110  		d := filepath.Join(dir, stepName)
   111  		copyRepo(oldDir, d)
   112  		repo := newRepo(d)
   113  		addKeys(repo, keys)
   114  
   115  		// Actually rotate the keys
   116  		revokeKeys(repo, role, roleKeys[role][0])
   117  		addKeys(repo, map[string][]*data.PrivateKey{
   118  			role: roleKeys[role][1],
   119  		})
   120  		keys[role] = roleKeys[role][1]
   121  
   122  		// Add a target to make sure that works, then commit.
   123  		addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
   124  		commit(d, repo)
   125  
   126  		i += 1
   127  		oldDir = d
   128  	}
   129  
   130  	// Add another target file to make sure the workflow worked.
   131  	stepName := fmt.Sprintf("%d", i)
   132  	d := filepath.Join(dir, stepName)
   133  	copyRepo(oldDir, d)
   134  	repo := newRepo(d)
   135  	addKeys(repo, keys)
   136  	addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
   137  	commit(d, repo)
   138  }
   139  
   140  func main() {
   141  	cwd, err := os.Getwd()
   142  	assertNoError(err)
   143  
   144  	for _, consistentSnapshot := range []bool{false, true} {
   145  		name := fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot)
   146  		log.Printf("generating %s", name)
   147  		generateRepos(filepath.Join(cwd, name), consistentSnapshot)
   148  	}
   149  
   150  }
   151  

View as plain text