Skip to content

Commit

Permalink
fixed import to be compatible with a flat key store and the direct te…
Browse files Browse the repository at this point in the history
…sts. Work is required on the integration tests still

Signed-off-by: Avi Vaid <[email protected]>
  • Loading branch information
avaid96 committed Aug 11, 2016
1 parent 1516bb7 commit b502a7c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 31 deletions.
47 changes: 21 additions & 26 deletions utils/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ func ImportKeys(from io.Reader, to []Importer, fallbackRole string, fallbackGun
toWrite []byte
)
for block, rest := pem.Decode(data); block != nil; block, rest = pem.Decode(rest) {
// if there is a path then we set the gun header from this path
if rawPath := block.Headers["path"]; rawPath != "" {
// if there is a lecacy path then we set the gun header from this path
if rawPath := block.Headers["path"]; rawPath != filepath.Base(rawPath) {
// this is a legacy filepath and we should try to deduce the gun name from it
pathWOFileName := strings.TrimSuffix(rawPath, filepath.Base(rawPath))
if strings.HasPrefix(pathWOFileName, notary.NonRootKeysSubdir) {
gunName := strings.TrimPrefix(pathWOFileName, notary.NonRootKeysSubdir)
Expand All @@ -117,53 +118,47 @@ func ImportKeys(from io.Reader, to []Importer, fallbackRole string, fallbackGun
}
}
}

if block.Headers["gun"] == "" {
if fallbackGun != "" {
block.Headers["gun"] = fallbackGun
}
}

if block.Headers["role"] == "" {
if fallbackRole == "" {
block.Headers["role"] = notary.DefaultImportRole
} else {
block.Headers["role"] = fallbackRole
}
}

// A root key or a delegations key should not have a gun
// Note that a key that is not any of the canonical roles (except root) is a delegations key and should not have a gun
if block.Headers["role"] != tufdata.CanonicalSnapshotRole && block.Headers["role"] != tufdata.CanonicalTargetsRole && block.Headers["role"] != tufdata.CanonicalTimestampRole {
delete(block.Headers, "gun")
} else {
// check if the key is missing a gun header or has an empty gun and error out since we don't know what gun it belongs to
if block.Headers["gun"] == "" {
logrus.Info("failed to import key to store: Cannot have canonical role key without a gun, don't know what gun it belongs to")
continue
}
}

loc, ok := block.Headers["path"]
// only if the path isn't specified do we get into this parsing path logic
if !ok || loc == "" {
// if the path isn't specified, we will try to infer the path rel to trust dir from the role (and then gun)
// parse key for the keyID which we will save it by.
// if the key is encrypted at this point, we will generate an error and continue since we don't know the ID to save it by

// note that any key exported by an older client
decodedKey, err := utils.ParsePEMPrivateKey(pem.EncodeToMemory(block), "")
if err != nil {
logrus.Info("failed to import key to store: Invalid key generated, key may be encrypted and does not contain path header")
continue
}
keyID := decodedKey.ID()
switch block.Headers["role"] {
case tufdata.CanonicalRootRole:
// this is a root key so import it to trustDir/root_keys/
loc = filepath.Join(notary.RootKeysSubdir, keyID)
case tufdata.CanonicalSnapshotRole, tufdata.CanonicalTargetsRole, tufdata.CanonicalTimestampRole:
// this is a canonical key
loc = filepath.Join(notary.NonRootKeysSubdir, block.Headers["gun"], keyID)
default:
//this is a delegation key
loc = filepath.Join(notary.NonRootKeysSubdir, keyID)
}
}

// A root key or a delegations key should not have a gun
// Note that a key that is not any of the canonical roles (except root) is a delegations key and should not have a gun
if block.Headers["role"] != tufdata.CanonicalSnapshotRole && block.Headers["role"] != tufdata.CanonicalTargetsRole && block.Headers["role"] != tufdata.CanonicalTimestampRole {
delete(block.Headers, "gun")
} else {
// check if the key is missing a gun header or has an empty gun and error out since we don't know where to import this key to
if block.Headers["gun"] == "" {
logrus.Info("failed to import key to store: Cannot have canonical role key without a gun, don't know where to import it")
continue
}
loc = decodedKey.ID()
}

// the path header is not of any use once we've imported the key so strip it away
Expand Down
11 changes: 6 additions & 5 deletions utils/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func TestImportNoPath(t *testing.T) {

for key := range s.data {
// no path but role included should work
require.Equal(t, key, filepath.Join(notary.RootKeysSubdir, "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497"))
require.Equal(t, "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497", key)
}

s = NewTestImportStore()
Expand All @@ -310,7 +310,7 @@ func TestNonRootPathInference(t *testing.T) {

for key := range s.data {
// no path but role included should work and 12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497 is the key ID of the fixture
require.Equal(t, key, filepath.Join(notary.NonRootKeysSubdir, "somegun", "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497"))
require.Equal(t, "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497", key)
}
}

Expand All @@ -333,7 +333,7 @@ func TestBlockHeaderPrecedenceRoleAndGun(t *testing.T) {
require.Len(t, s.data, 1)
for key := range s.data {
// block header role= root should take precedence over command line flag
require.Equal(t, key, filepath.Join(notary.NonRootKeysSubdir, "anothergun", "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497"))
require.Equal(t, "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497", key)
final, rest := pem.Decode(s.data[key])
require.Len(t, rest, 0)
require.Equal(t, final.Headers["role"], "snapshot")
Expand All @@ -342,6 +342,7 @@ func TestBlockHeaderPrecedenceRoleAndGun(t *testing.T) {
}

func TestBlockHeaderPrecedenceGunFromPath(t *testing.T) {
// this is a proof of concept that if we have legacy fixtures with nested paths, we infer the gun from them correctly
s := NewTestImportStore()

from, _ := os.OpenFile("../fixtures/secure.example.com.key", os.O_RDONLY, notary.PrivKeyPerms)
Expand Down Expand Up @@ -457,7 +458,7 @@ func TestImportKeys2InOneFileNoPath(t *testing.T) {
err := ImportKeys(in, []Importer{s}, "", "", passphraseRetriever)
require.NoError(t, err)

bFinal, bRest := pem.Decode(s.data[filepath.Join(notary.NonRootKeysSubdir, "testgun", "12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497")])
bFinal, bRest := pem.Decode(s.data["12ba0e0a8e05e177bc2c3489bdb6d28836879469f078e68a4812fc8a2d521497"])
require.Equal(t, b.Headers["gun"], bFinal.Headers["gun"])
require.Equal(t, b.Headers["role"], bFinal.Headers["role"])

Expand Down Expand Up @@ -541,7 +542,7 @@ func TestEncryption(t *testing.T) {
_ = ImportKeys(in, []Importer{s}, "", "", passphraseRetriever)
require.Len(t, s.data, 1)

shouldBeEnc, ok := s.data[filepath.Join(notary.NonRootKeysSubdir, privKey.ID())]
shouldBeEnc, ok := s.data[privKey.ID()]
// we should have got a key imported to this location
require.True(t, ok)

Expand Down

0 comments on commit b502a7c

Please sign in to comment.