mirror of https://github.com/docker/docs.git
make x509 certs viable as delegated public key object
Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
parent
2bf5d4b09a
commit
fa788cb2a9
|
@ -367,7 +367,7 @@ func (r *NotaryRepository) RemoveDelegation(name string) error {
|
|||
|
||||
// AddTarget creates new changelist entries to add a target to the given roles
|
||||
// in the repository when the changelist gets appied at publish time.
|
||||
// If roles are unspecified, the default role is "target".
|
||||
// If roles are unspecified, the default role is "targets".
|
||||
func (r *NotaryRepository) AddTarget(target *Target, roles ...string) error {
|
||||
|
||||
cl, err := changelist.NewFileChangelist(filepath.Join(r.tufRepoPath, "changelist"))
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
ctxu "github.com/docker/distribution/context"
|
||||
|
@ -1581,6 +1582,93 @@ func TestPublishDelegations(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Publishing delegations works so long as the delegation parent exists by the
|
||||
// time that delegation addition change is applied. Most of the tests for
|
||||
// applying delegation changes in in helpers_test.go (applyTargets tests), so
|
||||
// this is just a sanity test to make sure Publish calls it correctly and
|
||||
// no fallback happens.
|
||||
func TestPublishDelegationsX509(t *testing.T) {
|
||||
var tempDirs [2]string
|
||||
for i := 0; i < 2; i++ {
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
tempDirs[i] = tempBaseDir
|
||||
}
|
||||
|
||||
gun := "docker.com/notary"
|
||||
ts := fullTestServer(t)
|
||||
defer ts.Close()
|
||||
|
||||
repo1, _ := initializeRepo(t, data.ECDSAKey, tempDirs[0], gun, ts.URL, false)
|
||||
delgKey, err := repo1.CryptoService.Create("targets/a", data.ECDSAKey)
|
||||
assert.NoError(t, err, "error creating delegation key")
|
||||
|
||||
start := time.Now()
|
||||
privKey, _, err := repo1.CryptoService.GetPrivateKey(delgKey.ID())
|
||||
assert.NoError(t, err)
|
||||
cert, err := cryptoservice.GenerateCertificate(
|
||||
privKey, "targets/a", start, start.AddDate(1, 0, 0),
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
delgCert := data.NewECDSAx509PublicKey(trustmanager.CertToPEM(cert))
|
||||
|
||||
// This should publish fine, even though targets/a/b is dependent upon
|
||||
// targets/a, because these should execute in order
|
||||
for _, delgName := range []string{"targets/a", "targets/a/b", "targets/c"} {
|
||||
assert.NoError(t,
|
||||
repo1.AddDelegation(delgName, 1, []data.PublicKey{delgCert}, []string{""}),
|
||||
"error creating delegation")
|
||||
}
|
||||
assert.Len(t, getChanges(t, repo1), 3, "wrong number of changelist files found")
|
||||
assert.NoError(t, repo1.Publish())
|
||||
assert.Len(t, getChanges(t, repo1), 0, "wrong number of changelist files found")
|
||||
|
||||
// this should not publish, because targets/z doesn't exist
|
||||
assert.NoError(t,
|
||||
repo1.AddDelegation("targets/z/y", 1, []data.PublicKey{delgCert}, []string{""}),
|
||||
"error creating delegation")
|
||||
assert.Len(t, getChanges(t, repo1), 1, "wrong number of changelist files found")
|
||||
assert.Error(t, repo1.Publish())
|
||||
assert.Len(t, getChanges(t, repo1), 1, "wrong number of changelist files found")
|
||||
|
||||
// Create a new repo and pull from the server
|
||||
repo2, err := NewNotaryRepository(tempDirs[1], gun, ts.URL,
|
||||
http.DefaultTransport, passphraseRetriever)
|
||||
assert.NoError(t, err, "error creating repository: %s", err)
|
||||
|
||||
// pull
|
||||
_, err = repo2.ListTargets()
|
||||
assert.NoError(t, err, "unable to pull repo")
|
||||
|
||||
for _, repo := range []*NotaryRepository{repo1, repo2} {
|
||||
// targets should have delegations targets/a and targets/c
|
||||
targets := repo.tufRepo.Targets[data.CanonicalTargetsRole]
|
||||
assert.Len(t, targets.Signed.Delegations.Roles, 2)
|
||||
assert.Len(t, targets.Signed.Delegations.Keys, 1)
|
||||
|
||||
_, ok := targets.Signed.Delegations.Keys[delgCert.ID()]
|
||||
assert.True(t, ok)
|
||||
|
||||
foundRoleNames := make(map[string]bool)
|
||||
for _, r := range targets.Signed.Delegations.Roles {
|
||||
foundRoleNames[r.Name] = true
|
||||
}
|
||||
assert.True(t, foundRoleNames["targets/a"])
|
||||
assert.True(t, foundRoleNames["targets/c"])
|
||||
|
||||
// targets/a should have delegation targets/a/b only
|
||||
a := repo.tufRepo.Targets["targets/a"]
|
||||
assert.Len(t, a.Signed.Delegations.Roles, 1)
|
||||
assert.Len(t, a.Signed.Delegations.Keys, 1)
|
||||
|
||||
_, ok = a.Signed.Delegations.Keys[delgCert.ID()]
|
||||
assert.True(t, ok)
|
||||
|
||||
assert.Equal(t, "targets/a/b", a.Signed.Delegations.Roles[0].Name)
|
||||
}
|
||||
}
|
||||
|
||||
// If a changelist specifies a particular role to push targets to, and there
|
||||
// is no such role, publish will try to publish to its parent. If the parent
|
||||
// doesn't work, it falls back on its parent, and so forth, and eventually
|
||||
|
|
10
tuf/tuf.go
10
tuf/tuf.go
|
@ -530,11 +530,19 @@ func (tr *Repo) VerifyCanSign(roleName string) error {
|
|||
}
|
||||
|
||||
for _, keyID := range role.KeyIDs {
|
||||
p, _, err := tr.cryptoService.GetPrivateKey(keyID)
|
||||
k := tr.keysDB.GetKey(keyID)
|
||||
canonicalID, err := utils.CanonicalKeyID(k)
|
||||
check := []string{keyID}
|
||||
if err == nil {
|
||||
check = append(check, canonicalID)
|
||||
}
|
||||
for _, id := range check {
|
||||
p, _, err := tr.cryptoService.GetPrivateKey(id)
|
||||
if err == nil && p != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return signed.ErrNoKeys{KeyIDs: role.KeyIDs}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue