class WebofTrustVisualization(): def __init__(self, folder, pubkey=None): self.folder = folder self.gpg2_dir = os.path.join(folder, "gnupg") if not os.path.exists(self.folder): os.mkdir(self.folder) if os.path.exists(os.path.join(self.gpg2_dir, "pubring.gpg")) and not pubkey: print ("Continuing...") self.getNumber() self.gpg2 = GPG(gpgbinary="gpg2", gnupghome=self.gpg2_dir) elif not os.path.exists(self.gpg2_dir) and pubkey: print ("Initializing with key {}...".format(pubkey)) os.mkdir(self.gpg2_dir, mode=0o700) self.gpg2 = GPG(gpgbinary="gpg2", gnupghome=self.gpg2_dir) self.recv_keys(pubkey) self.number = 0 self.saveNumber() else: raise InvalidArgumentException def recv_keys(self, *pubkeys): self.gpg2.recv_keys("pgp.mit.edu", *pubkeys) def gendot(self): with open(os.path.join(self.folder, "{}.dot".format(self.number)), "w") as dot: with Popen(self.gpg2.make_args(["--list-sigs"], False), stdout=PIPE) as gpg2: Popen(["sig2dot", "-a"], stdin=gpg2.stdout, stdout=dot).wait() def draw(self, format="ps"): with open("{}.{}".format(os.path.join(self.folder, str(self.number)), format), "w") as drawing: Popen(["dot", "-T{}".format(format), "{}.dot".format(os.path.join(self.folder, str(self.number)))], stdout=drawing).wait() def nextRound(self): sigs_missing = [] print ("gpg2") with Popen(self.gpg2.make_args(["--list-sigs"], False), stdout=PIPE, env={"LANG": "C.UTF-8"}) as gpg2: for sig in gpg2.stdout.read().splitlines(): if b"[User ID not found]" in sig: for elem in sig.split(): if len(elem) == 8: if elem.decode() not in sigs_missing: #we need each key only once sigs_missing.append(elem.decode()) self.number += 1 #better safe than sorry self.saveNumber() self.recv_keys(*sigs_missing) def getNumber(self): with open(os.path.join(self.folder, "number"), "r") as number: self.number = int(number.read().strip()) def saveNumber(self): with open(os.path.join(self.folder, "number"), "w") as number: number.write(str(self.number))
def verify_gpg_signature(f): gpg = GPG(homedir='~/.gnupg') # search public key 0x90C8019E36C2E964 bitcoin_core_pgp_key_found = False keys = gpg.list_keys() for key in keys: if key['keyid'] == '90C8019E36C2E964': bitcoin_core_pgp_key_found = True if not bitcoin_core_pgp_key_found == True: print( '* Warning: bitcoin-core GPG key not found, trying to find and import...' ) import_key = gpg.recv_keys('90C8019E36C2E964', keyserver='hkp://pool.sks-keyservers.net') print('* Status: ' + import_key.summary()) print('* Fingerprint: ' + import_key.fingerprints[0]) with open(f) as fi: verif = gpg.verify_file(fi) print('* Verifying ' + f + ': ' + verif.status) if not verif.valid: print('* Impossible to compare checksums, quitting!') return verif.valid
class CommandHandler(object): def __init__(self): self.gpg = None self.gmail = None self.gpgmail = None self.initialized = False self.logger = logging.getLogger('CommandHandler') def parse(self, bundle): if not 'command' in bundle: self.logger.error("no command in bundle {}".format(bundle)) return None result = None command = bundle["command"] if command == 'init': result = self.init(bundle) else: # do nothing if not intialized if not self.initialized: return False if command == 'verify': result = self.verify(bundle) elif command == 'sign': result = self.sign(bundle) elif command == 'import': result = self.import_key(bundle) return result def init(self, bundle): if not 'username' in bundle: return False self.gpg = GPG(use_agent=True) self.gpgmail = GPGMail(self.gpg) self.gmail = Gmail(bundle['username']) self.initialized = True return {'version': VERSION} def verify(self, bundle): if not 'id' in bundle: return False id = bundle['id'] def _verify(): mail = self.gmail.get(id) return self.gpgmail.verify(mail) # verify the message only if bundle['force'] = true if 'force' in bundle and bundle['force']: return _verify() # or content_type of message is 'multipart/signed' headers = self.gmail.get_headers(id, ['Content-Type', 'Message-ID']) if 'Content-Type' in headers: content_type = headers['Content-Type'] if content_type.find('multipart/signed') >= 0: return _verify() # or if message is multipart and it may contain a pgp-signature is_multipart = content_type.find('multipart/') >= 0 if (is_multipart and 'Message-ID' in headers): rfc822msgid = headers['Message-ID'] query = 'filename:asc || filename:gpg || filename:signature || ("BEGIN PGP SIGNATURE" "END PGP SIGNATURE")' match = self.gmail.message_matches(id, query, rfc822msgid) if match: return _verify() # else return None def sign(self, bundle): if not 'id' in bundle: return False result = False id = bundle['id'] try: draft = self.gmail.get(id) new_message = self.gpgmail.sign(draft) if new_message: self.gmail.send(id, new_message) result = True except Exception as e: self.logger.exception(e) finally: return result def import_key(self, bundle): if not 'id' in bundle: return False imp = self.gpg.recv_keys('keyserver.ubuntu.com', bundle['id']) result = imp.imported > 0 complete_result = imp.results[0] self.logger.info("import key {} - {}: {}".format( complete_result['fingerprint'], result, complete_result['text'])) return result
class WebofTrustVisualization(): def __init__(self, folder, pubkey=None): self.folder = folder self.gpg2_dir = os.path.join(folder, "gnupg") if not os.path.exists(self.folder): os.mkdir(self.folder) if os.path.exists(os.path.join(self.gpg2_dir, "pubring.gpg")) and not pubkey: print("Continuing...") self.getNumber() self.gpg2 = GPG(gpgbinary="gpg2", gnupghome=self.gpg2_dir) elif not os.path.exists(self.gpg2_dir) and pubkey: print("Initializing with key {}...".format(pubkey)) os.mkdir(self.gpg2_dir, mode=0o700) self.gpg2 = GPG(gpgbinary="gpg2", gnupghome=self.gpg2_dir) self.recv_keys(pubkey) self.number = 0 self.saveNumber() else: raise InvalidArgumentException def recv_keys(self, *pubkeys): self.gpg2.recv_keys("pgp.mit.edu", *pubkeys) def gendot(self): with open(os.path.join(self.folder, "{}.dot".format(self.number)), "w") as dot: with Popen(self.gpg2.make_args(["--list-sigs"], False), stdout=PIPE) as gpg2: Popen(["sig2dot", "-a"], stdin=gpg2.stdout, stdout=dot).wait() def draw(self, format="ps"): with open( "{}.{}".format(os.path.join(self.folder, str(self.number)), format), "w") as drawing: Popen([ "dot", "-T{}".format(format), "{}.dot".format( os.path.join(self.folder, str(self.number))) ], stdout=drawing).wait() def nextRound(self): sigs_missing = [] print("gpg2") with Popen(self.gpg2.make_args(["--list-sigs"], False), stdout=PIPE, env={"LANG": "C.UTF-8"}) as gpg2: for sig in gpg2.stdout.read().splitlines(): if b"[User ID not found]" in sig: for elem in sig.split(): if len(elem) == 8: if elem.decode( ) not in sigs_missing: #we need each key only once sigs_missing.append(elem.decode()) self.number += 1 #better safe than sorry self.saveNumber() self.recv_keys(*sigs_missing) def getNumber(self): with open(os.path.join(self.folder, "number"), "r") as number: self.number = int(number.read().strip()) def saveNumber(self): with open(os.path.join(self.folder, "number"), "w") as number: number.write(str(self.number))