コード例 #1
0
ファイル: tuf.go プロジェクト: NathanMcCauley/notary
// VerifyCanSign returns nil if the role exists and we have at least one
// signing key for the role, false otherwise.  This does not check that we have
// enough signing keys to meet the threshold, since we want to support the use
// case of multiple signers for a role.  It returns an error if the role doesn't
// exist or if there are no signing keys.
func (tr *Repo) VerifyCanSign(roleName string) error {
	var (
		role data.BaseRole
		err  error
	)
	// we only need the BaseRole part of a delegation because we're just
	// checking KeyIDs
	if data.IsDelegation(roleName) {
		r, err := tr.GetDelegationRole(roleName)
		if err != nil {
			return err
		}
		role = r.BaseRole
	} else {
		role, err = tr.GetBaseRole(roleName)
	}
	if err != nil {
		return data.ErrInvalidRole{Role: roleName, Reason: "does not exist"}
	}

	for keyID, k := range role.Keys {
		check := []string{keyID}
		if canonicalID, err := utils.CanonicalKeyID(k); 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.ListKeyIDs()}
}
コード例 #2
0
ファイル: tuf.go プロジェクト: NathanMcCauley/notary
func (tr Repo) sign(signedData *data.Signed, role data.BaseRole) (*data.Signed, error) {
	ks := role.ListKeys()
	if len(ks) < 1 {
		return nil, signed.ErrNoKeys{}
	}
	err := signed.Sign(tr.cryptoService, signedData, ks...)
	if err != nil {
		return nil, err
	}
	return signedData, nil
}
コード例 #3
0
ファイル: verify.go プロジェクト: contiv/docker
// VerifySignatures checks the we have sufficient valid signatures for the given role
func VerifySignatures(s *data.Signed, roleData data.BaseRole) error {
	if len(s.Signatures) == 0 {
		return ErrNoSignatures
	}

	if roleData.Threshold < 1 {
		return ErrRoleThreshold{}
	}
	logrus.Debugf("%s role has key IDs: %s", roleData.Name, strings.Join(roleData.ListKeyIDs(), ","))

	// remarshal the signed part so we can verify the signature, since the signature has
	// to be of a canonically marshalled signed object
	var decoded map[string]interface{}
	if err := json.Unmarshal(s.Signed, &decoded); err != nil {
		return err
	}
	msg, err := json.MarshalCanonical(decoded)
	if err != nil {
		return err
	}

	valid := make(map[string]struct{})
	for _, sig := range s.Signatures {
		logrus.Debug("verifying signature for key ID: ", sig.KeyID)
		key, ok := roleData.Keys[sig.KeyID]
		if !ok {
			logrus.Debugf("continuing b/c keyid lookup was nil: %s\n", sig.KeyID)
			continue
		}
		// method lookup is consistent due to Unmarshal JSON doing lower case for us.
		method := sig.Method
		verifier, ok := Verifiers[method]
		if !ok {
			logrus.Debugf("continuing b/c signing method is not supported: %s\n", sig.Method)
			continue
		}

		if err := verifier.Verify(key, sig.Signature, msg); err != nil {
			logrus.Debugf("continuing b/c signature was invalid\n")
			continue
		}
		valid[sig.KeyID] = struct{}{}

	}
	if len(valid) < roleData.Threshold {
		return ErrRoleThreshold{}
	}

	return nil
}
コード例 #4
0
ファイル: verify.go プロジェクト: Mic92/docker
// VerifySignatures checks the we have sufficient valid signatures for the given role
func VerifySignatures(s *data.Signed, roleData data.BaseRole) error {
	if len(s.Signatures) == 0 {
		return ErrNoSignatures
	}

	if roleData.Threshold < 1 {
		return ErrRoleThreshold{}
	}
	logrus.Debugf("%s role has key IDs: %s", roleData.Name, strings.Join(roleData.ListKeyIDs(), ","))

	// remarshal the signed part so we can verify the signature, since the signature has
	// to be of a canonically marshalled signed object
	var decoded map[string]interface{}
	if err := json.Unmarshal(*s.Signed, &decoded); err != nil {
		return err
	}
	msg, err := json.MarshalCanonical(decoded)
	if err != nil {
		return err
	}

	valid := make(map[string]struct{})
	for i := range s.Signatures {
		sig := &(s.Signatures[i])
		logrus.Debug("verifying signature for key ID: ", sig.KeyID)
		key, ok := roleData.Keys[sig.KeyID]
		if !ok {
			logrus.Debugf("continuing b/c keyid lookup was nil: %s\n", sig.KeyID)
			continue
		}
		// Check that the signature key ID actually matches the content ID of the key
		if key.ID() != sig.KeyID {
			return ErrInvalidKeyID{}
		}
		if err := VerifySignature(msg, sig, key); err != nil {
			logrus.Debugf("continuing b/c %s", err.Error())
			continue
		}
		valid[sig.KeyID] = struct{}{}
	}
	if len(valid) < roleData.Threshold {
		return ErrRoleThreshold{
			Msg: fmt.Sprintf("valid signatures did not meet threshold for %s", roleData.Name),
		}
	}

	return nil
}
コード例 #5
0
ファイル: tuf.go プロジェクト: beerbubble/docker
// SignRoot signs the root, using all keys from the "root" role (i.e. currently trusted)
// as well as available keys used to sign the previous version, if the public part is
// carried in tr.Root.Keys and the private key is available (i.e. probably previously
// trusted keys, to allow rollover).  If there are any errors, attempt to put root
// back to the way it was (so version won't be incremented, for instance).
func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
	logrus.Debug("signing root...")

	// duplicate root and attempt to modify it rather than the existing root
	rootBytes, err := tr.Root.MarshalJSON()
	if err != nil {
		return nil, err
	}
	tempRoot := data.SignedRoot{}
	if err := json.Unmarshal(rootBytes, &tempRoot); err != nil {
		return nil, err
	}

	currRoot, err := tr.GetBaseRole(data.CanonicalRootRole)
	if err != nil {
		return nil, err
	}

	oldRootRoles := tr.getOldRootRoles()

	var latestSavedRole data.BaseRole
	rolesToSignWith := make([]data.BaseRole, 0, len(oldRootRoles))

	if len(oldRootRoles) > 0 {
		sort.Sort(oldRootRoles)
		for _, vRole := range oldRootRoles {
			rolesToSignWith = append(rolesToSignWith, vRole.BaseRole)
		}
		latest := rolesToSignWith[len(rolesToSignWith)-1]
		latestSavedRole = data.BaseRole{
			Name:      data.CanonicalRootRole,
			Threshold: latest.Threshold,
			Keys:      latest.Keys,
		}
	}

	// if the root role has changed and original role had not been saved as a previous role, save it now
	if !tr.originalRootRole.Equals(currRoot) && !tr.originalRootRole.Equals(latestSavedRole) {
		rolesToSignWith = append(rolesToSignWith, tr.originalRootRole)
		latestSavedRole = tr.originalRootRole

		versionName := oldRootVersionName(tempRoot.Signed.Version)
		tempRoot.Signed.Roles[versionName] = &data.RootRole{
			KeyIDs: latestSavedRole.ListKeyIDs(), Threshold: latestSavedRole.Threshold}

	}

	tempRoot.Signed.Expires = expires
	tempRoot.Signed.Version++

	// if the current role doesn't match with the latest saved role, save it
	if !currRoot.Equals(latestSavedRole) {
		rolesToSignWith = append(rolesToSignWith, currRoot)

		versionName := oldRootVersionName(tempRoot.Signed.Version)
		tempRoot.Signed.Roles[versionName] = &data.RootRole{
			KeyIDs: currRoot.ListKeyIDs(), Threshold: currRoot.Threshold}
	}

	signed, err := tempRoot.ToSigned()
	if err != nil {
		return nil, err
	}
	signed, err = tr.sign(signed, rolesToSignWith, tr.getOptionalRootKeys(rolesToSignWith))
	if err != nil {
		return nil, err
	}

	tr.Root = &tempRoot
	tr.Root.Signatures = signed.Signatures
	tr.originalRootRole = currRoot
	return signed, nil
}
コード例 #6
0
ファイル: tuf.go プロジェクト: CadeLaRen/docker-3
// SignRoot signs the root, using all keys from the "root" role (i.e. currently trusted)
// as well as available keys used to sign the previous version, if the public part is
// carried in tr.Root.Keys and the private key is available (i.e. probably previously
// trusted keys, to allow rollover).  If there are any errors, attempt to put root
// back to the way it was (so version won't be incremented, for instance).
func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
	logrus.Debug("signing root...")

	// duplicate root and attempt to modify it rather than the existing root
	rootBytes, err := tr.Root.MarshalJSON()
	if err != nil {
		return nil, err
	}
	tempRoot := data.SignedRoot{}
	if err := json.Unmarshal(rootBytes, &tempRoot); err != nil {
		return nil, err
	}

	currRoot, err := tr.GetBaseRole(data.CanonicalRootRole)
	if err != nil {
		return nil, err
	}

	oldRootRoles := tr.getOldRootRoles()

	var latestSavedRole data.BaseRole
	rolesToSignWith := make([]data.BaseRole, 0, len(oldRootRoles))

	if len(oldRootRoles) > 0 {
		sort.Sort(oldRootRoles)
		for _, vRole := range oldRootRoles {
			rolesToSignWith = append(rolesToSignWith, vRole.BaseRole)
		}
		latest := rolesToSignWith[len(rolesToSignWith)-1]
		latestSavedRole = data.BaseRole{
			Name:      data.CanonicalRootRole,
			Threshold: latest.Threshold,
			Keys:      latest.Keys,
		}
	}

	// If the root role (root keys or root threshold) has changed, save the
	// previous role under the role name "root.<n>", such that the "n" is the
	// latest root.json version for which previous root role was valid.
	// Also, guard against re-saving the previous role if the latest
	// saved role is the same (which should not happen).
	// n   = root.json version of the originalRootRole (previous role)
	// n+1 = root.json version of the currRoot (current role)
	// n-m = root.json version of latestSavedRole (not necessarily n-1, because the
	//       last root rotation could have happened several root.json versions ago
	if !tr.originalRootRole.Equals(currRoot) && !tr.originalRootRole.Equals(latestSavedRole) {
		rolesToSignWith = append(rolesToSignWith, tr.originalRootRole)
		latestSavedRole = tr.originalRootRole

		versionName := oldRootVersionName(tempRoot.Signed.Version)
		tempRoot.Signed.Roles[versionName] = &data.RootRole{
			KeyIDs: latestSavedRole.ListKeyIDs(), Threshold: latestSavedRole.Threshold}
	}

	tempRoot.Signed.Expires = expires
	tempRoot.Signed.Version++
	rolesToSignWith = append(rolesToSignWith, currRoot)

	signed, err := tempRoot.ToSigned()
	if err != nil {
		return nil, err
	}
	signed, err = tr.sign(signed, rolesToSignWith, tr.getOptionalRootKeys(rolesToSignWith))
	if err != nil {
		return nil, err
	}

	tr.Root = &tempRoot
	tr.Root.Signatures = signed.Signatures
	tr.originalRootRole = currRoot
	return signed, nil
}
コード例 #7
0
ファイル: tuf.go プロジェクト: vmware/vic
func (tr Repo) sign(signedData *data.Signed, role data.BaseRole) (*data.Signed, error) {
	if err := signed.Sign(tr.cryptoService, signedData, role.ListKeys()...); err != nil {
		return nil, err
	}
	return signedData, nil
}