Skip to content

Commit

Permalink
Ensure what we do not clobber local key id data for nested delegation…
Browse files Browse the repository at this point in the history
…s on list

Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
  • Loading branch information
riyazdf committed Jul 21, 2016
1 parent 0abcc1b commit b828631
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
17 changes: 10 additions & 7 deletions client/delegations.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func newDeleteDelegationChange(name string, content []byte) *changelist.TUFChang

// GetDelegationRoles returns the keys and roles of the repository's delegations
// Also converts key IDs to canonical key IDs to keep consistent with signing prompts
func (r *NotaryRepository) GetDelegationRoles() ([]*data.Role, error) {
func (r *NotaryRepository) GetDelegationRoles() ([]data.Role, error) {
// Update state of the repo to latest
if err := r.Update(false); err != nil {
return nil, err
Expand All @@ -251,7 +251,7 @@ func (r *NotaryRepository) GetDelegationRoles() ([]*data.Role, error) {
}

// make a copy for traversing nested delegations
allDelegations := []*data.Role{}
allDelegations := []data.Role{}

// Define a visitor function to populate the delegations list and translate their key IDs to canonical IDs
delegationCanonicalListVisitor := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
Expand All @@ -271,20 +271,23 @@ func (r *NotaryRepository) GetDelegationRoles() ([]*data.Role, error) {
return allDelegations, nil
}

func translateDelegationsToCanonicalIDs(delegationInfo data.Delegations) ([]*data.Role, error) {
canonicalDelegations := make([]*data.Role, len(delegationInfo.Roles))
copy(canonicalDelegations, delegationInfo.Roles)
func translateDelegationsToCanonicalIDs(delegationInfo data.Delegations) ([]data.Role, error) {
canonicalDelegations := make([]data.Role, len(delegationInfo.Roles))
// Do a copy by value to ensure local delegation metadata is untouched
for idx, origRole := range delegationInfo.Roles {
canonicalDelegations[idx] = *origRole
}
delegationKeys := delegationInfo.Keys
for i, delegation := range canonicalDelegations {
canonicalKeyIDs := []string{}
for _, keyID := range delegation.KeyIDs {
pubKey, ok := delegationKeys[keyID]
if !ok {
return nil, fmt.Errorf("Could not translate canonical key IDs for %s", delegation.Name)
return []data.Role{}, fmt.Errorf("Could not translate canonical key IDs for %s", delegation.Name)
}
canonicalKeyID, err := utils.CanonicalKeyID(pubKey)
if err != nil {
return nil, fmt.Errorf("Could not translate canonical key IDs for %s: %v", delegation.Name, err)
return []data.Role{}, fmt.Errorf("Could not translate canonical key IDs for %s: %v", delegation.Name, err)
}
canonicalKeyIDs = append(canonicalKeyIDs, canonicalKeyID)
}
Expand Down
52 changes: 52 additions & 0 deletions cmd/notary/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,58 @@ func TestClientDelegationsPublishing(t *testing.T) {
output, err = runCommand(t, tempDir, "-s", server.URL, "list", "gun", "--roles", "targets/releases")
require.NoError(t, err)
require.Contains(t, output, "targets/releases")

// Setup another certificate
tempFile2, err := ioutil.TempFile("", "pemfile2")
require.NoError(t, err)

privKey, err = utils.GenerateECDSAKey(rand.Reader)
startTime = time.Now()
endTime = startTime.AddDate(10, 0, 0)
cert, err = cryptoservice.GenerateCertificate(privKey, "gun", startTime, endTime)
require.NoError(t, err)

_, err = tempFile2.Write(utils.CertToPEM(cert))
require.NoError(t, err)
require.NoError(t, err)
tempFile2.Close()
defer os.Remove(tempFile2.Name())

rawPubBytes2, _ := ioutil.ReadFile(tempFile2.Name())
parsedPubKey2, _ := utils.ParsePEMPublicKey(rawPubBytes2)
keyID2, err := utils.CanonicalKeyID(parsedPubKey2)
require.NoError(t, err)

// add a nested delegation under this releases role
output, err = runCommand(t, tempDir, "delegation", "add", "gun", "targets/releases/nested", tempFile2.Name(), "--paths", "nested/path")
require.NoError(t, err)
require.Contains(t, output, "Addition of delegation role")
require.Contains(t, output, keyID2)

// publish repo
_, err = runCommand(t, tempDir, "-s", server.URL, "publish", "gun")
require.NoError(t, err)

// list delegations - we should see two roles
output, err = runCommand(t, tempDir, "-s", server.URL, "delegation", "list", "gun")
require.NoError(t, err)
require.Contains(t, output, "targets/releases")
require.Contains(t, output, "targets/releases/nested")
require.Contains(t, output, canonicalKeyID)
require.Contains(t, output, keyID2)
require.Contains(t, output, "nested/path")
require.Contains(t, output, "\"\"")
require.Contains(t, output, "<all paths>")

// remove by force to delete the nested delegation entirely
output, err = runCommand(t, tempDir, "delegation", "remove", "gun", "targets/releases/nested", "-y")
require.NoError(t, err)
require.Contains(t, output, "Forced removal (including all keys and paths) of delegation role")

// publish repo
_, err = runCommand(t, tempDir, "-s", server.URL, "publish", "gun")
require.NoError(t, err)

}

// Splits a string into lines, and returns any lines that are not empty (
Expand Down
4 changes: 2 additions & 2 deletions cmd/notary/prettyprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (t targetsSorter) Less(i, j int) bool {

// --- pretty printing roles ---

type roleSorter []*data.Role
type roleSorter []data.Role

func (r roleSorter) Len() int { return len(r) }
func (r roleSorter) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
Expand Down Expand Up @@ -173,7 +173,7 @@ func prettyPrintTargets(ts []*client.TargetWithRole, writer io.Writer) {
}

// Pretty-prints the list of provided Roles
func prettyPrintRoles(rs []*data.Role, writer io.Writer, roleType string) {
func prettyPrintRoles(rs []data.Role, writer io.Writer, roleType string) {
if len(rs) == 0 {
writer.Write([]byte(fmt.Sprintf("\nNo %s present in this repository.\n\n", roleType)))
return
Expand Down
4 changes: 2 additions & 2 deletions cmd/notary/prettyprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func TestPrettyPrintSortedTargets(t *testing.T) {
// are no roles.
func TestPrettyPrintZeroRoles(t *testing.T) {
var b bytes.Buffer
prettyPrintRoles([]*data.Role{}, &b, "delegations")
prettyPrintRoles([]data.Role{}, &b, "delegations")
text, err := ioutil.ReadAll(&b)
require.NoError(t, err)

Expand All @@ -218,7 +218,7 @@ func TestPrettyPrintZeroRoles(t *testing.T) {
func TestPrettyPrintSortedRoles(t *testing.T) {
var err error

unsorted := []*data.Role{
unsorted := []data.Role{
{Name: "targets/zebra", Paths: []string{"stripes", "black", "white"}, RootRole: data.RootRole{KeyIDs: []string{"101"}, Threshold: 1}},
{Name: "targets/aardvark/unicorn/pony", Paths: []string{"rainbows"}, RootRole: data.RootRole{KeyIDs: []string{"135"}, Threshold: 1}},
{Name: "targets/bee", Paths: []string{"honey"}, RootRole: data.RootRole{KeyIDs: []string{"246"}, Threshold: 1}},
Expand Down

0 comments on commit b828631

Please sign in to comment.