def test_commit_signer_has_signed_ca(self): """ Verify that whoever signed the commit has also signed the contributor agreement / copyright assignment. """ if sys.version_info < (3, 0, 0): self.skipTest("no pgpy on this python version") import pgpy # pylint: disable=import-error repodir = get_repo_dir() feature_sha1 = os.environ.get("TRAVIS_PULL_REQUEST_SHA") signer_encoded = subprocess.check_output( ["git", "show", "-s", r'--pretty="%GK"', feature_sha1], cwd=repodir).decode("utf-8").strip().strip('"') with open(os.path.join( repodir, "cmakelang/contrib/signature_db.json")) as infile: sigdb = json.load(infile) for sigentry in sigdb: clearsign = format_signature(sigentry["signature"]) sig = pgpy.PGPSignature() sig.parse(clearsign) if sig.signer == signer_encoded: return self.fail("Could not find signer {} in signature database".format( signer_encoded))
def importSignature(signature: typing.Union[Path, bytes]): if isinstance(signature, Path): with MMap(signature) as m: return importSignature(m) else: s = pgpy.PGPSignature() return s.parse(signature)
def verify(pub_key, message, signature): pub_key, _ = pgpy.PGPKey.from_blob(pub_key) temp_pgpy = pgpy.PGPSignature() temp_pgpy.parse(signature) if pub_key.verify(message, temp_pgpy): return True else: return False
def get_signature_informations(self): """Get message signature features.""" signed_parts = [ x for x in self.message.attachments if 'pgp-sign' in x.content_type ] if not signed_parts: return {} sign = pgpy.PGPSignature() features = {'message_signed': True, 'message_signature_type': 'PGP'} try: sign.parse(signed_parts[0].data) features.update({'message_signer': sign.signer}) except Exception as exc: log.error('Unable to parse pgp signature {}'.format(exc)) return features
def verify_signature( self, *, data: bytes, armored_detached_signature: str, armored_public_key: str, ) -> bool: # Load sig signature: pgpy.PGPSignature = pgpy.PGPSignature() signature.parse(armored_detached_signature) # Load key key: pgpy.PGPKey = pgpy.PGPKey() key.parse(armored_public_key) # Verify verified: pgpy.types.SignatureVerification = key.verify( data, signature) is_verified: bool = bool(verified) return is_verified
def verify(self, authors: Manager) -> VerifiedMessage: try: author = authors.get(email=self.sender_address) except ObjectDoesNotExist: raise AuthorUnknown(self.sender_address) if not author.pgp_public_key: raise AuthorNotVerifyable(author) expected_public_key = pgpy.PGPKey() expected_public_key.parse(author.pgp_public_key) # Mandatory: Verify Signature if not self._signature: raise NoSignature(self) attached_signature = pgpy.PGPSignature() attached_signature.parse(self._signature) # Verify signature if not (attached_signature.signer_fingerprint == expected_public_key.fingerprint): raise SignatureMismatch(expected_public_key.fingerprint, attached_signature.signer_fingerprint) # Optional: If a public key was attached, verify it for good measure if self._public_key: attached_pub_key = pgpy.PGPKey() attached_pub_key.parse(self._public_key) # Verify public Key if not expected_public_key.fingerprint == attached_pub_key.fingerprint: raise PublicKeyMismatch(expected_public_key, attached_pub_key) return VerifiedMessage(subject=self._message.get('subject'), body=self._body, author=author)
def test_signatures(self): """ Iterate over signatures and verify them. """ gpg_argv = ["gpg", "--homedir", self.homedir] if sys.version_info < (3, 0, 0): self.skipTest("no pgpy on this python version") # TODO(josh): For some reason importing pgpy seems to cause the # stderr filedescriptor to leak when we subprocess below. pgpy must be # doing some ugly subprocess thing on it's own warnings.simplefilter("ignore", ResourceWarning) # TODO(josh): pgpy seems to import distutils and the version distributed # with virtualenv on this system has an outdated import of `imp` instead # of `importlib`. with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) import pgpy # pylint: disable=import-error repodir = get_repo_dir() with open(os.path.join( repodir, "cmakelang/contrib/signature_db.json")) as infile: sigdb = json.load(infile) # First, get a list of keys already in the local keyring known_fingerprints = set() proc = subprocess.Popen(gpg_argv + ["--fingerprint", "--with-colons"], stdout=subprocess.PIPE) for line in proc.stdout: parts = line.decode("utf-8").split(":") if parts[0] == "fpr": fingerprint = parts[-2] known_fingerprints.add(fingerprint[-16:]) proc.wait() # Now do a scan through the database and get a list of any keys we are # missing needkeys = [] for sigentry in sigdb: clearsign = format_signature(sigentry["signature"]) sig = pgpy.PGPSignature() sig.parse(clearsign) if sig.signer not in known_fingerprints: needkeys.append(sig.signer) if needkeys: # TODO(josh): use SKS pool instead of specific server result = subprocess.check_call( gpg_argv + ["--keyserver", "keyserver.ubuntu.com", "--recv-keys"] + needkeys) self.assertEqual(result, 0, msg="Failed to fetch all keys from keyserver") with open(os.path.join( repodir, "cmakelang/contrib/individual_ca.txt")) as infile: template = infile.read() # Then verify all the signatures for sigentry in sigdb: clearsign = format_signature(sigentry["signature"]) document = construct_agreement_text(template, sigentry) with tempfile.NamedTemporaryFile(delete=False) as outfile: outfile.write(clearsign.encode("utf-8")) detached_sig = outfile.name with tempfile.NamedTemporaryFile(delete=False) as outfile: outfile.write(document.encode("utf-8")) document_msg = outfile.name with open(os.devnull, "w") as devnull: proc = subprocess.Popen( gpg_argv + ["--verify", detached_sig, document_msg], stderr=devnull) result = proc.wait() self.assertEqual(0, result, msg="Failed to verify signature for {}\n\n" "See {} and {}".format(sigentry["name"], detached_sig, document_msg)) os.unlink(detached_sig) os.unlink(document_msg)
def test_signatures(self): """ Iterate over signatures and verify them. """ if sys.version_info < (3, 0, 0): self.skipTest("no pgpy on this python version") import pgpy # pylint: disable=import-error repodir = get_repo_dir() with open( os.path.join( repodir, "cmake_format/contrib/signature_db.json")) as infile: sigdb = json.load(infile) # First, get a list of keys already in the local keyring known_fingerprints = set() proc = subprocess.Popen(["gpg", "--fingerprint", "--with-colons"], stdout=subprocess.PIPE) for line in proc.stdout: parts = line.decode("utf-8").split(":") if parts[0] == "fpr": fingerprint = parts[-2] known_fingerprints.add(fingerprint[-16:]) proc.wait() # Now do a scan through the database and get a list of any keys we are # missing needkeys = [] for sigentry in sigdb: clearsign = format_signature(sigentry["signature"]) sig = pgpy.PGPSignature() sig.parse(clearsign) if sig.signer not in known_fingerprints: needkeys.append(sig.signer) if needkeys: # TODO(josh): use SKS pool instead of specific server result = subprocess.check_call( ["gpg", "--keyserver", "keyserver.ubuntu.com", "--recv-keys"] + needkeys) self.assertEqual(result, 0, msg="Failed to fetch all keys from keyserver") with open( os.path.join( repodir, "cmake_format/contrib/individual_ca.txt")) as infile: template = infile.read() # Then verify all the signatures for sigentry in sigdb: clearsign = format_signature(sigentry["signature"]) document = construct_agreement_text(template, sigentry) with tempfile.NamedTemporaryFile(delete=False) as outfile: outfile.write(clearsign.encode("utf-8")) detached_sig = outfile.name with tempfile.NamedTemporaryFile(delete=False) as outfile: outfile.write(document.encode("utf-8")) document_msg = outfile.name with open(os.devnull, "w") as devnull: proc = subprocess.Popen( ["gpg", "--verify", detached_sig, document_msg], stderr=devnull) result = proc.wait() self.assertEqual(0, result, msg="Failed to verify signature for {}\n\n" "See {} and {}".format(sigentry["name"], detached_sig, document_msg)) os.unlink(detached_sig) os.unlink(document_msg)