コード例 #1
0
ファイル: client.go プロジェクト: NathanMcCauley/notary
func (c Client) verifyRoot(role string, s *data.Signed, minVersion int) error {
	// this will confirm that the root has been signed by the old root role
	// with the root keys we bootstrapped with.
	// Still need to determine if there has been a root key update and
	// confirm signature with new root key
	logrus.Debug("verifying root with existing keys")
	rootRole, err := c.local.GetBaseRole(role)
	if err != nil {
		logrus.Debug("no previous root role loaded")
		return err
	}
	// Verify using the rootRole loaded from the known root.json
	if err = signed.Verify(s, rootRole, minVersion); err != nil {
		logrus.Debug("root did not verify with existing keys")
		return err
	}

	logrus.Debug("updating known root roles and keys")
	root, err := data.RootFromSigned(s)
	if err != nil {
		logrus.Error(err.Error())
		return err
	}
	// replace the existing root.json with the new one (just in memory, we
	// have another validation step before we fully accept the new root)
	err = c.local.SetRoot(root)
	if err != nil {
		logrus.Error(err.Error())
		return err
	}
	// Verify the new root again having loaded the rootRole out of this new
	// file (verifies self-referential integrity)
	// TODO(endophage): be more intelligent and only re-verify if we detect
	//                  there has been a change in root keys
	logrus.Debug("verifying root with updated keys")
	rootRole, err = c.local.GetBaseRole(role)
	if err != nil {
		logrus.Debug("root role with new keys not loaded")
		return err
	}
	err = signed.Verify(s, rootRole, minVersion)
	if err != nil {
		logrus.Debug("root did not verify with new keys")
		return err
	}
	logrus.Debug("successfully verified root")
	return nil
}
コード例 #2
0
ファイル: validation.go プロジェクト: rogaha/notary
func validateSnapshot(role string, oldSnap *data.SignedSnapshot, snapUpdate storage.MetaUpdate, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) error {
	s := &data.Signed{}
	err := json.Unmarshal(snapUpdate.Data, s)
	if err != nil {
		return errors.New("could not parse snapshot")
	}
	// version specifically gets validated when writing to store to
	// better handle race conditions there.
	if err := signed.Verify(s, role, 0, kdb); err != nil {
		return err
	}

	snap, err := data.SnapshotFromSigned(s)
	if err != nil {
		return errors.New("could not parse snapshot")
	}
	if !data.ValidTUFType(snap.Signed.Type, data.CanonicalSnapshotRole) {
		return errors.New("snapshot has wrong type")
	}
	err = checkSnapshotEntries(role, oldSnap, snap, roles)
	if err != nil {
		return err
	}
	return nil
}
コード例 #3
0
ファイル: client.go プロジェクト: DaveDaCoda/docker
// downloadTimestamp is responsible for downloading the timestamp.json
// Timestamps are special in that we ALWAYS attempt to download and only
// use cache if the download fails (and the cache is still valid).
func (c *Client) downloadTimestamp() error {
	logrus.Debug("downloadTimestamp")
	role := data.RoleName("timestamp")

	// We may not have a cached timestamp if this is the first time
	// we're interacting with the repo. This will result in the
	// version being 0
	var download bool
	old := &data.Signed{}
	version := 0
	cachedTS, err := c.cache.GetMeta(role, maxSize)
	if err == nil {
		err := json.Unmarshal(cachedTS, old)
		if err == nil {
			ts, err := data.TimestampFromSigned(old)
			if err == nil {
				version = ts.Signed.Version
			}
		} else {
			old = nil
		}
	}
	// unlike root, targets and snapshot, always try and download timestamps
	// from remote, only using the cache one if we couldn't reach remote.
	raw, s, err := c.downloadSigned(role, maxSize, nil)
	if err != nil || len(raw) == 0 {
		if err, ok := err.(store.ErrMetaNotFound); ok {
			return err
		}
		if old == nil {
			if err == nil {
				// couldn't retrieve data from server and don't have valid
				// data in cache.
				return store.ErrMetaNotFound{}
			}
			return err
		}
		logrus.Debug("using cached timestamp")
		s = old
	} else {
		download = true
	}
	err = signed.Verify(s, role, version, c.keysDB)
	if err != nil {
		return err
	}
	logrus.Debug("successfully verified timestamp")
	if download {
		c.cache.SetMeta(role, raw)
	}
	ts, err := data.TimestampFromSigned(s)
	if err != nil {
		return err
	}
	c.local.SetTimestamp(ts)
	return nil
}
コード例 #4
0
ファイル: client.go プロジェクト: sreenuyedavalli/docker
// downloadTimestamp is responsible for downloading the timestamp.json
// Timestamps are special in that we ALWAYS attempt to download and only
// use cache if the download fails (and the cache is still valid).
func (c *Client) downloadTimestamp() error {
	logrus.Debug("Downloading Timestamp...")
	role := data.CanonicalTimestampRole

	// We may not have a cached timestamp if this is the first time
	// we're interacting with the repo. This will result in the
	// version being 0
	var (
		saveToCache bool
		old         *data.Signed
		version     = 0
	)
	cachedTS, err := c.cache.GetMeta(role, maxSize)
	if err == nil {
		cached := &data.Signed{}
		err := json.Unmarshal(cachedTS, cached)
		if err == nil {
			ts, err := data.TimestampFromSigned(cached)
			if err == nil {
				version = ts.Signed.Version
			}
			old = cached
		}
	}
	// unlike root, targets and snapshot, always try and download timestamps
	// from remote, only using the cache one if we couldn't reach remote.
	raw, s, err := c.downloadSigned(role, maxSize, nil)
	if err != nil || len(raw) == 0 {
		if old == nil {
			if err == nil {
				// couldn't retrieve data from server and don't have valid
				// data in cache.
				return store.ErrMetaNotFound{Resource: data.CanonicalTimestampRole}
			}
			return err
		}
		logrus.Debug(err.Error())
		logrus.Warn("Error while downloading remote metadata, using cached timestamp - this might not be the latest version available remotely")
		s = old
	} else {
		saveToCache = true
	}
	err = signed.Verify(s, role, version, c.keysDB)
	if err != nil {
		return err
	}
	logrus.Debug("successfully verified timestamp")
	if saveToCache {
		c.cache.SetMeta(role, raw)
	}
	ts, err := data.TimestampFromSigned(s)
	if err != nil {
		return err
	}
	c.local.SetTimestamp(ts)
	return nil
}
コード例 #5
0
ファイル: client.go プロジェクト: NathanMcCauley/notary
// verifies that a timestamp is valid, and returned the SignedTimestamp object to add to the tuf repo
func (c *Client) verifyTimestamp(s *data.Signed, minVersion int) (*data.SignedTimestamp, error) {
	timestampRole, err := c.local.GetBaseRole(data.CanonicalTimestampRole)
	if err != nil {
		logrus.Debug("no timestamp role loaded")
		return nil, err
	}
	if err := signed.Verify(s, timestampRole, minVersion); err != nil {
		return nil, err
	}
	return data.TimestampFromSigned(s)
}
コード例 #6
0
ファイル: swizzler_test.go プロジェクト: moxiegirl/notary
// This changes the root key
func TestSwizzlerChangeRootKey(t *testing.T) {
	f, origMeta := createNewSwizzler(t)

	f.ChangeRootKey()

	tufRepo := tuf.NewRepo(f.CryptoService)

	// we want to test these in a specific order
	roles := []string{data.CanonicalRootRole, data.CanonicalTargetsRole, data.CanonicalSnapshotRole,
		data.CanonicalTimestampRole, "targets/a", "targets/a/b"}

	for _, role := range roles {
		origMeta := origMeta[role]
		newMeta, err := f.MetadataCache.GetMeta(role, -1)
		require.NoError(t, err)

		// the threshold for base roles is set in root
		switch role {
		case data.CanonicalRootRole:
			require.False(t, bytes.Equal(origMeta, newMeta))
			origRoot, newRoot := &data.SignedRoot{}, &data.SignedRoot{}
			require.NoError(t, json.Unmarshal(origMeta, origRoot))
			require.NoError(t, json.Unmarshal(newMeta, newRoot))

			require.NotEqual(t, len(origRoot.Signed.Keys), len(newRoot.Signed.Keys))

			var rootRole data.Role
			for r, origRole := range origRoot.Signed.Roles {
				newRole := newRoot.Signed.Roles[r]
				require.Len(t, origRole.KeyIDs, 1)
				require.Len(t, newRole.KeyIDs, 1)
				if r == data.CanonicalRootRole {
					require.NotEqual(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
					rootRole = data.Role{RootRole: *newRole, Name: data.CanonicalRootRole}
				} else {
					require.Equal(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
				}
			}

			require.NoError(t, tufRepo.SetRoot(newRoot))
			signedThing, err := newRoot.ToSigned()
			require.NoError(t, err)
			newKey := newRoot.Signed.Keys[rootRole.KeyIDs[0]]
			require.NoError(t, signed.Verify(signedThing,
				data.BaseRole{Name: data.CanonicalRootRole, Keys: map[string]data.PublicKey{newKey.ID(): newKey}, Threshold: 1}, 1))
		default:
			require.True(t, bytes.Equal(origMeta, newMeta), "bytes have changed for role %s", role)
		}
	}
}
コード例 #7
0
ファイル: client.go プロジェクト: DaveDaCoda/docker
func (c Client) verifyRoot(role string, s *data.Signed, minVersion int) error {
	// this will confirm that the root has been signed by the old root role
	// as c.keysDB contains the root keys we bootstrapped with.
	// Still need to determine if there has been a root key update and
	// confirm signature with new root key
	logrus.Debug("verifying root with existing keys")
	err := signed.Verify(s, role, minVersion, c.keysDB)
	if err != nil {
		logrus.Debug("root did not verify with existing keys")
		return err
	}

	// This will cause keyDB to get updated, overwriting any keyIDs associated
	// with the roles in root.json
	logrus.Debug("updating known root roles and keys")
	root, err := data.RootFromSigned(s)
	if err != nil {
		logrus.Error(err.Error())
		return err
	}
	err = c.local.SetRoot(root)
	if err != nil {
		logrus.Error(err.Error())
		return err
	}
	// verify again now that the old keys have been replaced with the new keys.
	// TODO(endophage): be more intelligent and only re-verify if we detect
	//                  there has been a change in root keys
	logrus.Debug("verifying root with updated keys")
	err = signed.Verify(s, role, minVersion, c.keysDB)
	if err != nil {
		logrus.Debug("root did not verify with new keys")
		return err
	}
	logrus.Debug("successfully verified root")
	return nil
}
コード例 #8
0
ファイル: validation.go プロジェクト: rogaha/notary
func validateTargets(role string, roles map[string]storage.MetaUpdate, kdb *keys.KeyDB) (*data.SignedTargets, error) {
	// TODO: when delegations are being validated, validate parent
	//       role exists for any delegation
	s := &data.Signed{}
	err := json.Unmarshal(roles[role].Data, s)
	if err != nil {
		return nil, fmt.Errorf("could not parse %s", role)
	}
	// version specifically gets validated when writing to store to
	// better handle race conditions there.
	if err := signed.Verify(s, role, 0, kdb); err != nil {
		return nil, err
	}
	t, err := data.TargetsFromSigned(s)
	if err != nil {
		return nil, err
	}
	if !data.ValidTUFType(t.Signed.Type, data.CanonicalTargetsRole) {
		return nil, fmt.Errorf("%s has wrong type", role)
	}
	return t, nil
}
コード例 #9
0
ファイル: validation.go プロジェクト: NathanMcCauley/notary
func validateTargets(role string, roles map[string]storage.MetaUpdate, repo *tuf.Repo) (*data.SignedTargets, error) {
	// TODO: when delegations are being validated, validate parent
	//       role exists for any delegation
	s := &data.Signed{}
	err := json.Unmarshal(roles[role].Data, s)
	if err != nil {
		return nil, fmt.Errorf("could not parse %s", role)
	}
	// version specifically gets validated when writing to store to
	// better handle race conditions there.
	var targetOrDelgRole data.BaseRole
	if role == data.CanonicalTargetsRole {
		targetOrDelgRole, err = repo.GetBaseRole(role)
		if err != nil {
			logrus.Debugf("no %s role loaded", role)
			return nil, err
		}
	} else {
		delgRole, err := repo.GetDelegationRole(role)
		if err != nil {
			logrus.Debugf("no %s delegation role loaded", role)
			return nil, err
		}
		targetOrDelgRole = delgRole.BaseRole
	}
	if err := signed.Verify(s, targetOrDelgRole, 0); err != nil {
		return nil, err
	}
	t, err := data.TargetsFromSigned(s)
	if err != nil {
		return nil, err
	}
	if !data.ValidTUFType(t.Signed.Type, data.CanonicalTargetsRole) {
		return nil, fmt.Errorf("%s has wrong type", role)
	}
	return t, nil
}
コード例 #10
0
ファイル: client.go プロジェクト: DaveDaCoda/docker
func (c Client) getTargetsFile(role string, keyIDs []string, snapshotMeta data.Files, consistent bool, threshold int) (*data.Signed, error) {
	// require role exists in snapshots
	roleMeta, ok := snapshotMeta[role]
	if !ok {
		return nil, ErrMissingMeta{role: role}
	}
	expectedSha256, ok := snapshotMeta[role].Hashes["sha256"]
	if !ok {
		return nil, ErrMissingMeta{role: role}
	}

	// try to get meta file from content addressed cache
	var download bool
	old := &data.Signed{}
	version := 0
	raw, err := c.cache.GetMeta(role, roleMeta.Length)
	if err != nil || raw == nil {
		logrus.Debugf("Couldn't not find cached %s, must download", role)
		download = true
	} else {
		// file may have been tampered with on disk. Always check the hash!
		genHash := sha256.Sum256(raw)
		if !bytes.Equal(genHash[:], expectedSha256) {
			download = true
		}
		err := json.Unmarshal(raw, old)
		if err == nil {
			targ, err := data.TargetsFromSigned(old)
			if err == nil {
				version = targ.Signed.Version
			} else {
				download = true
			}
		} else {
			download = true
		}
	}

	size := snapshotMeta[role].Length
	var s *data.Signed
	if download {
		rolePath, err := c.RoleTargetsPath(role, hex.EncodeToString(expectedSha256), consistent)
		if err != nil {
			return nil, err
		}
		raw, s, err = c.downloadSigned(rolePath, size, expectedSha256)
		if err != nil {
			return nil, err
		}
	} else {
		logrus.Debug("using cached ", role)
		s = old
	}

	err = signed.Verify(s, role, version, c.keysDB)
	if err != nil {
		return nil, err
	}
	logrus.Debugf("successfully verified %s", role)
	if download {
		// if we error when setting meta, we should continue.
		err = c.cache.SetMeta(role, raw)
		if err != nil {
			logrus.Errorf("Failed to write snapshot to local cache: %s", err.Error())
		}
	}
	return s, nil
}
コード例 #11
0
ファイル: client.go プロジェクト: DaveDaCoda/docker
// downloadSnapshot is responsible for downloading the snapshot.json
func (c *Client) downloadSnapshot() error {
	logrus.Debug("downloadSnapshot")
	role := data.RoleName("snapshot")
	if c.local.Timestamp == nil {
		return ErrMissingMeta{role: "snapshot"}
	}
	size := c.local.Timestamp.Signed.Meta[role].Length
	expectedSha256, ok := c.local.Timestamp.Signed.Meta[role].Hashes["sha256"]
	if !ok {
		return ErrMissingMeta{role: "snapshot"}
	}

	var download bool
	old := &data.Signed{}
	version := 0
	raw, err := c.cache.GetMeta(role, size)
	if raw == nil || err != nil {
		logrus.Debug("no snapshot in cache, must download")
		download = true
	} else {
		// file may have been tampered with on disk. Always check the hash!
		genHash := sha256.Sum256(raw)
		if !bytes.Equal(genHash[:], expectedSha256) {
			logrus.Debug("hash of snapshot in cache did not match expected hash, must download")
			download = true
		}
		err := json.Unmarshal(raw, old)
		if err == nil {
			snap, err := data.TimestampFromSigned(old)
			if err == nil {
				version = snap.Signed.Version
			} else {
				logrus.Debug("Could not parse Signed part of snapshot, must download")
				download = true
			}
		} else {
			logrus.Debug("Could not parse snapshot, must download")
			download = true
		}
	}
	var s *data.Signed
	if download {
		raw, s, err = c.downloadSigned(role, size, expectedSha256)
		if err != nil {
			return err
		}
	} else {
		logrus.Debug("using cached snapshot")
		s = old
	}

	err = signed.Verify(s, role, version, c.keysDB)
	if err != nil {
		return err
	}
	logrus.Debug("successfully verified snapshot")
	snap, err := data.SnapshotFromSigned(s)
	if err != nil {
		return err
	}
	c.local.SetSnapshot(snap)
	if download {
		err = c.cache.SetMeta(role, raw)
		if err != nil {
			logrus.Errorf("Failed to write snapshot to local cache: %s", err.Error())
		}
	}
	return nil
}
コード例 #12
0
ファイル: client.go プロジェクト: carriercomm/notary
// verifies that a timestamp is valid, and returned the SignedTimestamp object to add to the tuf repo
func (c *Client) verifyTimestamp(s *data.Signed, minVersion int, kdb *keys.KeyDB) (*data.SignedTimestamp, error) {
	if err := signed.Verify(s, data.CanonicalTimestampRole, minVersion, kdb); err != nil {
		return nil, err
	}
	return data.TimestampFromSigned(s)
}
コード例 #13
0
ファイル: client.go プロジェクト: contiv/docker
func (c Client) getTargetsFile(role string, snapshotMeta data.Files, consistent bool) (*data.Signed, error) {
	// require role exists in snapshots
	roleMeta, ok := snapshotMeta[role]
	if !ok {
		return nil, data.ErrMissingMeta{Role: role}
	}
	expectedSha256, ok := snapshotMeta[role].Hashes["sha256"]
	if !ok {
		return nil, data.ErrMissingMeta{Role: role}
	}

	// try to get meta file from content addressed cache
	var download bool
	old := &data.Signed{}
	version := 0
	raw, err := c.cache.GetMeta(role, roleMeta.Length)
	if err != nil || raw == nil {
		logrus.Debugf("Couldn't not find cached %s, must download", role)
		download = true
	} else {
		// file may have been tampered with on disk. Always check the hash!
		genHash := sha256.Sum256(raw)
		if !bytes.Equal(genHash[:], expectedSha256) {
			download = true
		}
		err := json.Unmarshal(raw, old)
		if err == nil {
			targ, err := data.TargetsFromSigned(old, role)
			if err == nil {
				version = targ.Signed.Version
			} else {
				download = true
			}
		} else {
			download = true
		}
	}

	size := snapshotMeta[role].Length
	var s *data.Signed
	if download {
		raw, s, err = c.downloadSigned(role, size, expectedSha256)
		if err != nil {
			return nil, err
		}
	} else {
		logrus.Debug("using cached ", role)
		s = old
	}
	var targetOrDelgRole data.BaseRole
	if data.IsDelegation(role) {
		delgRole, err := c.local.GetDelegationRole(role)
		if err != nil {
			logrus.Debugf("no %s delegation role loaded", role)
			return nil, err
		}
		targetOrDelgRole = delgRole.BaseRole
	} else {
		targetOrDelgRole, err = c.local.GetBaseRole(role)
		if err != nil {
			logrus.Debugf("no %s role loaded", role)
			return nil, err
		}
	}
	if err = signed.Verify(s, targetOrDelgRole, version); err != nil {
		return nil, err
	}
	logrus.Debugf("successfully verified %s", role)
	if download {
		// if we error when setting meta, we should continue.
		err = c.cache.SetMeta(role, raw)
		if err != nil {
			logrus.Errorf("Failed to write %s to local cache: %s", role, err.Error())
		}
	}
	return s, nil
}
コード例 #14
0
ファイル: client.go プロジェクト: beerbubble/docker
// downloadSnapshot is responsible for downloading the snapshot.json
func (c *Client) downloadSnapshot() error {
	logrus.Debug("Downloading Snapshot...")
	role := data.CanonicalSnapshotRole
	if c.local.Timestamp == nil {
		return tuf.ErrNotLoaded{Role: data.CanonicalTimestampRole}
	}
	size := c.local.Timestamp.Signed.Meta[role].Length
	expectedHashes := c.local.Timestamp.Signed.Meta[role].Hashes
	if len(expectedHashes) == 0 {
		return data.ErrMissingMeta{Role: data.CanonicalSnapshotRole}
	}

	var download bool
	old := &data.Signed{}
	version := 0
	raw, err := c.cache.GetMeta(role, size)
	if raw == nil || err != nil {
		logrus.Debug("no snapshot in cache, must download")
		download = true
	} else {
		// file may have been tampered with on disk. Always check the hash!
		if err := data.CheckHashes(raw, expectedHashes); err != nil {
			logrus.Debug("hash of snapshot in cache did not match expected hash, must download")
			download = true
		}

		err := json.Unmarshal(raw, old)
		if err == nil {
			snap, err := data.SnapshotFromSigned(old)
			if err == nil {
				version = snap.Signed.Version
			} else {
				logrus.Debug("Could not parse Signed part of snapshot, must download")
				download = true
			}
		} else {
			logrus.Debug("Could not parse snapshot, must download")
			download = true
		}
	}
	var s *data.Signed
	if download {
		raw, s, err = c.downloadSigned(role, size, expectedHashes)
		if err != nil {
			return err
		}
	} else {
		logrus.Debug("using cached snapshot")
		s = old
	}

	snapshotRole, err := c.local.GetBaseRole(role)
	if err != nil {
		logrus.Debug("no snapshot role loaded")
		return err
	}
	err = signed.Verify(s, snapshotRole, version)
	if err != nil {
		return err
	}
	logrus.Debug("successfully verified snapshot")
	snap, err := data.SnapshotFromSigned(s)
	if err != nil {
		return err
	}
	c.local.SetSnapshot(snap)
	if download {
		err = c.cache.SetMeta(role, raw)
		if err != nil {
			logrus.Errorf("Failed to write snapshot to local cache: %s", err.Error())
		}
	}
	return nil
}