Esempio n. 1
0
        def verify_sig(self, acts, pub, trust_anchors, use_crls,
            required_names=None):
                """Try to verify this signature.  It can return True or
                None.  None means we didn't know how to verify this signature.
                If we do know how to verify the signature but it doesn't verify,
                then an exception is raised.

                The 'acts' parameter is the iterable of actions against which
                to verify the signature.

                The 'pub' parameter is the publisher that published the
                package this action signed.

                The 'trust_anchors' parameter contains the trust anchors to use
                when verifying the signature.

                The 'required_names' parameter is a set of strings that must
                be seen as a CN in the chain of trust for the certificate."""

                ver = int(self.attrs["version"])
                # If this signature is tagged with variants, if the version is
                # higher than one we know about, or it uses an unrecognized
                # hash algorithm, we can't handle it yet.
                if self.get_variant_template() or \
                    ver > generic.Action.sig_version or not self.hash_alg:
                        return None
                # Turning this into a list makes debugging vastly more
                # tractable.
                acts = list(acts)
                # If self.hash is None, then the signature is storing a hash
                # of the actions, not a signed value.
                if self.hash is None:
                        assert self.sig_alg is None
                        dgst = m2.EVP.MessageDigest(self.hash_alg)
                        res = dgst.update(self.actions_to_str(acts, ver))
                        assert res == 1, \
                            "Res was expected to be 1, but was %s" % res
                        computed_hash = dgst.final()
                        # The attrs value is stored in hex so that it's easy
                        # to read.
                        if misc.hex_to_binary(self.attrs["value"]) != \
                            computed_hash:
                                raise apx.UnverifiedSignature(self,
                                    _("The signature value did not match the "
                                    "expected value. action:%s") % self)
                        return True
                # Verify a signature that's not just a hash.
                if self.sig_alg is None:
                        return None
                # Get the certificate paired with the key which signed this
                # action.
                cert = pub.get_cert_by_hash(self.hash, verify_hash=True)
                # Make sure that the intermediate certificates that are needed
                # to validate this signature are present.
                self.retrieve_chain_certs(pub)
                try:
                        # This import is placed here to break a circular
                        # import seen when merge.py is used.
                        from pkg.client.publisher import CODE_SIGNING_USE
                        # Verify the certificate whose key created this
                        # signature action.
                        pub.verify_chain(cert, trust_anchors, 0, use_crls,
                            required_names=required_names,
                            usages=CODE_SIGNING_USE)
                except apx.SigningException, e:
                        e.act = self
                        raise
Esempio n. 2
0
    def verify_sig(self,
                   acts,
                   pub,
                   trust_anchors,
                   use_crls,
                   required_names=None):
        """Try to verify this signature.  It can return True or
                None.  None means we didn't know how to verify this signature.
                If we do know how to verify the signature but it doesn't verify,
                then an exception is raised.

                The 'acts' parameter is the iterable of actions against which
                to verify the signature.

                The 'pub' parameter is the publisher that published the
                package this action signed.

                The 'trust_anchors' parameter contains the trust anchors to use
                when verifying the signature.

                The 'required_names' parameter is a set of strings that must
                be seen as a CN in the chain of trust for the certificate."""

        ver = int(self.attrs["version"])
        # If this signature is tagged with variants, if the version is
        # higher than one we know about, or it uses an unrecognized
        # hash algorithm, we can't handle it yet.
        if self.get_variant_template() or \
            ver > generic.Action.sig_version or not self.hash_alg:
            return None
        # Turning this into a list makes debugging vastly more
        # tractable.
        acts = list(acts)
        # If self.hash is None, then the signature is storing a hash
        # of the actions, not a signed value.
        if self.hash is None:
            assert self.sig_alg is None
            h = hashlib.new(self.hash_alg)
            h.update(misc.force_bytes(self.actions_to_str(acts, ver)))
            computed_hash = h.digest()
            # The attrs value is stored in hex so that it's easy
            # to read.
            if misc.hex_to_binary(self.attrs["value"]) != \
                computed_hash:
                raise apx.UnverifiedSignature(
                    self,
                    _("The signature value did not match the "
                      "expected value. action: {0}").format(self))
            return True
        # Verify a signature that's not just a hash.
        if self.sig_alg is None:
            return None
        # Get the certificate paired with the key which signed this
        # action.
        attr, hash_val, hash_func = \
            digest.get_least_preferred_hash(self)
        cert = pub.get_cert_by_hash(hash_val,
                                    verify_hash=True,
                                    hash_func=hash_func)
        # Make sure that the intermediate certificates that are needed
        # to validate this signature are present.
        self.retrieve_chain_certs(pub)
        try:
            # This import is placed here to break a circular
            # import seen when merge.py is used.
            from pkg.client.publisher import CODE_SIGNING_USE
            # Verify the certificate whose key created this
            # signature action.
            pub.verify_chain(cert,
                             trust_anchors,
                             0,
                             use_crls,
                             required_names=required_names,
                             usages=CODE_SIGNING_USE)
        except apx.SigningException as e:
            e.act = self
            raise
        # Check that the certificate verifies against this signature.
        pub_key = cert.public_key()
        hhash = self.__get_hash_by_name(self.hash_alg)
        signature = misc.hex_to_binary(self.attrs["value"])

        try:
            pub_key.verify(signature,
                           misc.force_bytes(self.actions_to_str(acts, ver)),
                           padding.PKCS1v15(), hhash())
        except InvalidSignature:
            raise apx.UnverifiedSignature(
                self,
                _("The signature value did not match the expected "
                  "value."))

        return True
Esempio n. 3
0
                        # import seen when merge.py is used.
                        from pkg.client.publisher import CODE_SIGNING_USE
                        # Verify the certificate whose key created this
                        # signature action.
                        pub.verify_chain(cert, trust_anchors, 0, use_crls,
                            required_names=required_names,
                            usages=CODE_SIGNING_USE)
                except apx.SigningException, e:
                        e.act = self
                        raise
                # Check that the certificate verifies against this signature.
                pub_key = cert.get_pubkey(md=self.hash_alg)
                pub_key.verify_init()
                pub_key.verify_update(self.actions_to_str(acts, ver))
                res = pub_key.verify_final(
                    misc.hex_to_binary(self.attrs["value"]))
                if not res:
                        raise apx.UnverifiedSignature(self,
                            _("The signature value did not match the expected "
                            "value. Res: %s") % res)
                return True

        def set_signature(self, acts, key_path=None, chain_paths=misc.EmptyI,
            chash_dir=None):
                """Sets the signature value for this action.

                The 'acts' parameter is the iterable of actions this action
                should sign.

                The 'key_path' parameter is the path to the file containing the
                private key which is used to sign the actions.