+
+ # Case 1:
+ # Allow non authority to sign target and cred about target.
+ #
+ # Why do we need to allow non authorities to sign?
+ # If in the target gid validation step we correctly
+ # checked that the target is only signed by an authority,
+ # then this is just a special case of case 3.
+ # This short-circuit is the common case currently -
+ # and cause GID validation doesn't check 'authority',
+ # this allows users to generate valid slice credentials.
+ if root_target_gid.is_signed_by_cert(root_cred_signer):
+ # cred signer matches target signer, return success
+ return
+
+ # Case 2:
+ # Allow someone to sign credential about themeselves. Used?
+ # If not, remove this.
+ #root_target_gid_str = root_target_gid.save_to_string()
+ #root_cred_signer_str = root_cred_signer.save_to_string()
+ #if root_target_gid_str == root_cred_signer_str:
+ # # cred signer is target, return success
+ # return
+
+ # Case 3:
+
+ # root_cred_signer is not the target_gid
+ # So this is a different gid that we have not verified.
+ # xmlsec1 verified the cert chain on this already, but
+ # it hasn't verified that the gid meets the HRN namespace
+ # requirements.
+ # Below we'll ensure that it is an authority.
+ # But we haven't verified that it is _signed by_ an authority
+ # We also don't know if xmlsec1 requires that cert signers
+ # are marked as CAs.
+
+ # Note that if verify() gave us no trusted_gids then this
+ # call will fail. So skip it if we have no trusted_gids
+ if trusted_gids and len(trusted_gids) > 0:
+ root_cred_signer.verify_chain(trusted_gids)
+ else:
+ logger.debug("No trusted gids. Cannot verify that cred signer is signed by a trusted authority. Skipping that check.")
+
+ # See if the signer is an authority over the domain of the target.
+ # There are multiple types of authority - accept them all here
+ # Maybe should be (hrn, type) = urn_to_hrn(root_cred_signer.get_urn())
+ root_cred_signer_type = root_cred_signer.get_type()
+ if (root_cred_signer_type.find('authority') == 0):
+ #logger.debug('Cred signer is an authority')
+ # signer is an authority, see if target is in authority's domain
+ signerhrn = root_cred_signer.get_hrn()
+ if hrn_authfor_hrn(signerhrn, root_target_gid.get_hrn()):
+ return
+
+ # We've required that the credential be signed by an authority
+ # for that domain. Reasonable and probably correct.
+ # A looser model would also allow the signer to be an authority
+ # in my control framework - eg My CA or CH. Even if it is not
+ # the CH that issued these, eg, user credentials.
+
+ # Give up, credential does not pass issuer verification
+
+ raise CredentialNotVerifiable("Could not verify credential owned by %s for object %s. Cred signer %s not the trusted authority for Cred target %s" % (self.gidCaller.get_urn(), self.gidObject.get_urn(), root_cred_signer.get_hrn(), root_target_gid.get_hrn()))
+