Beispiel #1
0
func (rb *repoBuilder) loadTargets(content []byte, minVersion int, allowExpired bool) error {
	roleName := data.CanonicalTargetsRole

	targetsRole, err := rb.repo.Root.BuildBaseRole(roleName)
	if err != nil { // this should never happen, since it's already been validated
		return err
	}

	signedObj, err := rb.bytesToSignedAndValidateSigs(targetsRole, content)
	if err != nil {
		return err
	}

	signedTargets, err := data.TargetsFromSigned(signedObj, roleName)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedTargets.Signed.SignedCommon), minVersion); err != nil {
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedTargets.Signed.SignedCommon), roleName); err != nil {
			return err
		}
	}

	signedTargets.Signatures = signedObj.Signatures
	rb.repo.Targets[roleName] = signedTargets
	return nil
}
Beispiel #2
0
func (rb *repoBuilder) loadTimestamp(content []byte, minVersion int, allowExpired bool) error {
	roleName := data.CanonicalTimestampRole

	timestampRole, err := rb.repo.Root.BuildBaseRole(roleName)
	if err != nil { // this should never happen, since it's already been validated
		return err
	}

	signedObj, err := rb.bytesToSignedAndValidateSigs(timestampRole, content)
	if err != nil {
		return err
	}

	signedTimestamp, err := data.TimestampFromSigned(signedObj)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedTimestamp.Signed.SignedCommon), minVersion); err != nil {
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedTimestamp.Signed.SignedCommon), roleName); err != nil {
			return err
		}
	}

	if err := rb.validateChecksumsFromTimestamp(signedTimestamp); err != nil {
		return err
	}

	rb.repo.Timestamp = signedTimestamp
	return nil
}
Beispiel #3
0
// loadRoot loads a root if one has not been loaded
func (rb *repoBuilder) loadRoot(content []byte, minVersion int, allowExpired bool) error {
	roleName := data.CanonicalRootRole

	signedObj, err := rb.bytesToSigned(content, data.CanonicalRootRole)
	if err != nil {
		return err
	}
	// ValidateRoot validates against the previous root's role, as well as validates that the root
	// itself is self-consistent with its own signatures and thresholds.
	// This assumes that ValidateRoot calls data.RootFromSigned, which validates
	// the metadata, rather than just unmarshalling signedObject into a SignedRoot object itself.
	signedRoot, err := trustpinning.ValidateRoot(rb.prevRoot, signedObj, rb.gun, rb.trustpin)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedRoot.Signed.SignedCommon), minVersion); err != nil {
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedRoot.Signed.SignedCommon), roleName); err != nil {
			return err
		}
	}

	rootRole, err := signedRoot.BuildBaseRole(data.CanonicalRootRole)
	if err != nil { // this should never happen since the root has been validated
		return err
	}
	rb.repo.Root = signedRoot
	rb.repo.originalRootRole = rootRole
	return nil
}
Beispiel #4
0
func (rb *repoBuilder) loadDelegation(roleName string, content []byte, minVersion int, allowExpired bool) error {
	delegationRole, err := rb.repo.GetDelegationRole(roleName)
	if err != nil {
		return err
	}

	signedObj, err := rb.bytesToSignedAndValidateSigs(delegationRole.BaseRole, content)
	if err != nil {
		return err
	}

	signedTargets, err := data.TargetsFromSigned(signedObj, roleName)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedTargets.Signed.SignedCommon), minVersion); err != nil {
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedTargets.Signed.SignedCommon), roleName); err != nil {
			return err
		}
	}

	rb.repo.Targets[roleName] = signedTargets
	return nil
}
Beispiel #5
0
// This changes the root key
func TestSwizzlerChangeRootKey(t *testing.T) {
	f, origMeta := createNewSwizzler(t)

	err := f.ChangeRootKey()
	require.NoError(t, err)

	// 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, store.NoSizeLimit)
		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))

			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])
				} else {
					require.Equal(t, origRole.KeyIDs[0], newRole.KeyIDs[0])
				}
			}

			rootRole, err := newRoot.BuildBaseRole(data.CanonicalRootRole)
			require.NoError(t, err)
			signedThing, err := newRoot.ToSigned()
			require.NoError(t, err)
			require.NoError(t, signed.VerifySignatures(signedThing, rootRole))
			require.NoError(t, signed.VerifyVersion(&(newRoot.Signed.SignedCommon), 1))
		default:
			require.True(t, bytes.Equal(origMeta, newMeta), "bytes have changed for role %s", role)
		}
	}
}
Beispiel #6
0
func (rb *repoBuilder) loadSnapshot(content []byte, minVersion int, allowExpired bool) error {
	roleName := data.CanonicalSnapshotRole

	snapshotRole, err := rb.repo.Root.BuildBaseRole(roleName)
	if err != nil { // this should never happen, since it's already been validated
		return err
	}

	signedObj, err := rb.bytesToSignedAndValidateSigs(snapshotRole, content)
	if err != nil {
		return err
	}

	signedSnapshot, err := data.SnapshotFromSigned(signedObj)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedSnapshot.Signed.SignedCommon), minVersion); err != nil {
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedSnapshot.Signed.SignedCommon), roleName); err != nil {
			return err
		}
	}

	// at this point, the only thing left to validate is existing checksums - we can use
	// this snapshot to bootstrap the next builder if needed - and we don't need to do
	// the 2-value assignment since we've already validated the signedSnapshot, which MUST
	// have root metadata
	rootMeta := signedSnapshot.Signed.Meta[data.CanonicalRootRole]
	rb.nextRootChecksum = &rootMeta

	if err := rb.validateChecksumsFromSnapshot(signedSnapshot); err != nil {
		return err
	}

	rb.repo.Snapshot = signedSnapshot
	return nil
}
Beispiel #7
0
func (rb *repoBuilder) loadDelegation(roleName string, content []byte, minVersion int, allowExpired bool) error {
	delegationRole, err := rb.repo.GetDelegationRole(roleName)
	if err != nil {
		return err
	}

	// bytesToSigned checks checksum
	signedObj, err := rb.bytesToSigned(content, roleName)
	if err != nil {
		return err
	}

	signedTargets, err := data.TargetsFromSigned(signedObj, roleName)
	if err != nil {
		return err
	}

	if err := signed.VerifyVersion(&(signedTargets.Signed.SignedCommon), minVersion); err != nil {
		// don't capture in invalidRoles because the role we received is a rollback
		return err
	}

	// verify signature
	if err := signed.VerifySignatures(signedObj, delegationRole.BaseRole); err != nil {
		rb.invalidRoles.Targets[roleName] = signedTargets
		return err
	}

	if !allowExpired { // check must go at the end because all other validation should pass
		if err := signed.VerifyExpiry(&(signedTargets.Signed.SignedCommon), roleName); err != nil {
			rb.invalidRoles.Targets[roleName] = signedTargets
			return err
		}
	}

	signedTargets.Signatures = signedObj.Signatures
	rb.repo.Targets[roleName] = signedTargets
	return nil
}