def gpg_gen_key(name): """ Generates keys gpg """ if not os.path.exists(gpghome): os.mkdir(gpghome, 0o700) # create a blank configuration file with open(os.path.join(gpghome, 'gpg.conf'), 'wv') as handle: handle.write('') if not gpg_exist_key(name): # create a context ctx = gpgme.Context() key_params = """ <GnupgKeyParms format="internal"> Key-Type: RSA Key-Length: 4096 Name-Real: %s Expire-Date: 0 </GnupgKeyParms> """ ctx.genkey(key_params % name) return gpg_exist_key(name)
def presence(self, stanza): """Presence stanza received.""" ptype = stanza.getAttribute('type') if ptype == 'subscribe': # sign received public key for child in stanza.pubkey.children: if child.name == 'print': fpr = str(child) break myfpr = str(self.config['publickey']['fingerprint']) ctx = gpgme.Context() ctx.signers = [ctx.get_key(myfpr, True)] gpgme.editutil.edit_sign(ctx, ctx.get_key(fpr), check=0) keydata = BytesIO() ctx.export(fpr, keydata) r = xmlstream.toResponse(stanza, 'subscribed') pubkey = r.addElement(('urn:xmpp:pubkey:2', 'pubkey')) key = pubkey.addElement((None, 'key')) key.addContent(base64.b64encode(keydata.getvalue())) fprint = pubkey.addElement((None, 'print')) fprint.addContent(fpr) self.client.send(r)
def test_speed(self): email_body = """Hello, this is my email body, which shall be signed.""" ctx = gpgme.Context() key = ctx.get_key('5F503EFAC8C89323D54C252591B8CD7E15925678') ctx.signers = [key] plaintext = BytesIO(email_body.encode()) signature = BytesIO() start = timer() n = 100 for i in range(n): plaintext.seek(0) signature.seek(0) sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) self.assertEqual(len(sigs), 1) sig = sigs[0] self.assertEqual(sig.type, gpgme.SIG_MODE_CLEAR) self.assertIsInstance(sig, gpgme.NewSignature) end = timer() time_spent = end - start # in fractions of seconds #print("\nTime elapsed for {:d} iterations: {:.3f}".format(n, time_spent)) #print("That is {:.1f} signatures per second.".format(n/time_spent)) #we want to process at least 12 per second self.assertTrue(n / time_spent > 12)
def test_sign_clearsign(self): ctx = gpgme.Context() ctx.armor = True key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] plaintext = StringIO.StringIO('Hello World\n') signature = StringIO.StringIO() new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_CLEAR) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # now verify the signature signature.seek(0) plaintext = StringIO.StringIO() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), 'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None)
def test_verify_clearsign(self): signature = StringIO.StringIO( dedent(''' -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello World -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDz7DiRrtV8IhcZaQRAjuYAJ43/NhhNHx+gzGBUqtIK5LpENTCGgCfV3aO ZTFlGRyKN26HccsC6ZWcPUQ= =kZ2c -----END PGP SIGNATURE----- ''')) plaintext = StringIO.StringIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), 'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137684706) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None)
def handle(self, **options): self.community_domains = [ '@' + domain for domain in settings.PKS_COMMUNITY_DOMAINS ] full_names = set() for mafiasi in Mafiasi.objects.all(): full_names.add(mafiasi.get_full_name()) self.full_names = full_names ctx = gpgme.Context() ctx.keylist_mode = gpgme.KEYLIST_MODE_SIGS keys = ctx.keylist() foreign_keys = [] for key in keys: if not self.is_community(key): foreign_keys.append(key) fingerprints = [] for key in foreign_keys: fingerprint = '0x' + key.subkeys[0].fpr uid = key.uids[0] print('{}: {} <{}>'.format(fingerprint, uid.name, uid.email)) fingerprints.append(fingerprint) print('\ngpg --batch --delete-key ' + ' '.join(fingerprints))
def test_import_secret_file(self): ctx = gpgme.Context() with self.keyfile('key1.sec') as fp: result = ctx.import_(fp) self.assertEqual(result.considered, 1) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 1) self.assertEqual(result.imported_rsa, 0) self.assertEqual(result.unchanged, 0) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 0) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 1) self.assertEqual(result.secret_imported, 1) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 2) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW | gpgme.IMPORT_SECRET)) self.assertEqual(result.imports[1], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # can we get the secret key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4', True)
def test_decrypt(self): ciphertext = StringIO.StringIO( dedent(''' -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.1 (GNU/Linux) hQIMA6lSIdANy91kARAAtXjViihD6DVBAYGdVs0a2sMPGRXjIR5Tw1ONKx4MtKn+ pydR+/+0rBRGaQXe/mMODA8gqADQjz7PcTMWBa7ja969+K2nw7j5DUIMatonQVMf vpc7ze5hovZ1jXYAgmmXdUzDmk8ZkpHaEc5mMMAHYKFn+mm37AFY5JUjg2Ae9k3H 29t+pW+n9ncn/QBImW3oVslZ8Fza1xOIWZTUrmvtU0vELdlIxy+d945bvD9EhmTK zRrD5m8V1etWINO2tE1Xhd4lV1KxncHzWafXLB5BKprztTqFUXNPAfnucYIczDon 5VvkOz3WAtl/93o85hUKhbgGK0dvU3m+bj620ZUE5oDpPB4l1CiO5RqUFYtyN4LF OSAceVOh7X764VLtpAzuOpNfTYgvzIFJqrFOZHlf3XJRdGdpJuxMe8BwhdLyDscx pap4QxajOUSUAeS45x6ERA7xHO0QOwXZNzoxiOt9KRaoIhEacu70A9xRcGNJfZE2 3z/AEMKr2CK6ny9/S8UQEhNvn1/gYfSXakFjWjM6PUXJSnz8WGjpFKKITpex3WBz m/X8bKgG3fT92zqJdYocrl4wgz4Dt3+KirnGG4gITxaEYpTT0y6l6NAO60De0oRh yqk+ulj2pvAlA82Ph0vTGZ9uOQGbrfN+NhwsG0HMNq+vmjShS1jJbSfoEt1AAIPS RwGMq7SDk/V7nhKqZcxeIWdtRIgFvEf0KljthkOZxT/GozNjQclak7Kt69K2qyvt XUfidNAhuOmeZ4pF31qSFiAnKRbzjzHp =1s5N -----END PGP MESSAGE----- ''')) plaintext = StringIO.StringIO() ctx = gpgme.Context() ctx.decrypt(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), 'hello world\n')
def __init__(self, config, config_provider): if not config.get("GPG2_PRIVATE_KEY_NAME"): raise Exception("Missing configuration key GPG2_PRIVATE_KEY_NAME") if not config.get("GPG2_PRIVATE_KEY_FILENAME"): raise Exception( "Missing configuration key GPG2_PRIVATE_KEY_FILENAME") if not config.get("GPG2_PUBLIC_KEY_FILENAME"): raise Exception( "Missing configuration key GPG2_PUBLIC_KEY_FILENAME") self._ctx = gpgme.Context() self._ctx.armor = True self._private_key_name = config["GPG2_PRIVATE_KEY_NAME"] self._public_key_filename = config["GPG2_PUBLIC_KEY_FILENAME"] self._config_provider = config_provider if not config_provider.volume_file_exists( config["GPG2_PRIVATE_KEY_FILENAME"]): raise Exception("Missing key file %s" % config["GPG2_PRIVATE_KEY_FILENAME"]) with config_provider.get_volume_file( config["GPG2_PRIVATE_KEY_FILENAME"], mode="rb") as fp: self._ctx.import_(fp)
def test_import_twice(self): ctx = gpgme.Context() fp = self.keyfile('key1.pub') result = ctx.import_(fp) fp = self.keyfile('key1.pub') result = ctx.import_(fp) self.assertEqual(result.considered, 1) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 0) self.assertEqual(result.imported_rsa, 0) self.assertEqual(result.unchanged, 1) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 0) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 0) self.assertEqual(result.secret_imported, 0) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 1) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, 0)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4')
def test_encrypt_sign(self): plaintext = StringIO.StringIO('Hello World\n') ciphertext = StringIO.StringIO() ctx = gpgme.Context() ctx.armor = True signer = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') recipient = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.signers = [signer] new_sigs = ctx.encrypt_sign([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_NORMAL) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # rewind ciphertext buffer, and try to decrypt: ciphertext.seek(0) plaintext = StringIO.StringIO() sigs = ctx.decrypt_verify(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), 'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None)
def generate_elbe_internal_key(): hostfs.mkdir_p("/var/cache/elbe/gnupg") os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg" ctx = gpgme.Context() key = ctx.genkey(elbe_internal_key_param) return key.fpr
def get_key(keyid, validate=False, encrypt=False, sign=False): """ Gets a key from the keyring by filtering for the specified keyid, but only if the given keyid is specific enough (if it matches multiple keys, an exception will be thrown). :param keyid: filter term for the keyring (usually a key ID) :rtype: gpgme.Key """ ctx = gpgme.Context() try: key = ctx.get_key(keyid) if validate: validate_key(key, encrypt=encrypt, sign=sign) except gpgme.GpgmeError as e: if e.code == gpgme.ERR_AMBIGUOUS_NAME: raise GPGProblem(("More than one key found matching this filter." + " Please be more specific (use a key ID like " + "4AC8EE1D)."), code=GPGCode.AMBIGUOUS_NAME) elif e.code == gpgme.ERR_INV_VALUE or e.code == gpgme.ERR_EOF: raise GPGProblem("Can not find key for \'" + keyid + "\'.", code=GPGCode.NOT_FOUND) else: raise e return key
def get_key(keyid, validate=False, encrypt=False, sign=False): """ Gets a key from the keyring by filtering for the specified keyid, but only if the given keyid is specific enough (if it matches multiple keys, an exception will be thrown). If validate is True also make sure that returned key is not invalid, revoked or expired. In addition if encrypt or sign is True also validate that key is valid for that action. For example only keys with private key can sign. :param keyid: filter term for the keyring (usually a key ID) :param validate: validate that returned keyid is valid :param encrypt: when validating confirm that returned key can encrypt :param sign: when validating confirm that returned key can sign :rtype: gpgme.Key """ ctx = gpgme.Context() try: key = ctx.get_key(keyid) if validate: validate_key(key, encrypt=encrypt, sign=sign) except gpgme.GpgmeError as e: if e.code == gpgme.ERR_AMBIGUOUS_NAME: # When we get here it means there were multiple keys returned by gpg # for given keyid. Unfortunately gpgme returns invalid and expired # keys together with valid keys. If only one key is valid for given # operation maybe we can still return it instead of raising # exception keys = list_keys(hint=keyid) valid_key = None for k in keys: try: validate_key(k, encrypt=encrypt, sign=sign) except GPGProblem: # if the key is invalid for given action skip it continue if valid_key: # we have already found one valid key and now we find # another? We really received an ambiguous keyid raise GPGProblem( ("More than one key found matching " + "this filter. Please be more " + "specific (use a key ID like " + "4AC8EE1D)."), code=GPGCode.AMBIGUOUS_NAME) valid_key = k if not valid_key: # there were multiple keys found but none of them are valid for # given action (we don't have private key, they are expired etc) raise GPGProblem("Can not find usable key for \'" + keyid + "\'.", code=GPGCode.NOT_FOUND) return valid_key elif e.code == gpgme.ERR_INV_VALUE or e.code == gpgme.ERR_EOF: raise GPGProblem("Can not find key for \'" + keyid + "\'.", code=GPGCode.NOT_FOUND) else: raise e return key
def generateKey(self, name): """See `IGPGHandler`.""" context = gpgme.Context() # Make sure that gpg-agent doesn't interfere. if 'GPG_AGENT_INFO' in os.environ: del os.environ['GPG_AGENT_INFO'] # Only 'utf-8' encoding is supported by gpgme. # See more information at: # http://pyme.sourceforge.net/doc/gpgme/Generating-Keys.html result = context.genkey(signing_only_param % {'name': name.encode('utf-8')}) # Right, it might seem paranoid to have this many assertions, # but we have to take key generation very seriously. assert result.primary, 'Secret key generation failed.' assert not result.sub, ( 'Only sign-only RSA keys are safe to be generated') secret_keys = list(self.localKeys(result.fpr, secret=True)) assert len(secret_keys) == 1, 'Found %d secret GPG keys for %s' % ( len(secret_keys), result.fpr) key = secret_keys[0] assert key.fingerprint == result.fpr, ( 'The key in the local keyring does not match the one generated.') assert key.exists_in_local_keyring, ( 'The key does not seem to exist in the local keyring.') return key
def write_sums_file(root, found_files, status, hash_algorithm): # Clean out any stale sums files for supported_algorithm in HASH_ALGORITHMS: sums_file = os.path.join(root, supported_algorithm + 'sums.asc') if os.path.exists(sums_file): os.unlink(sums_file) if not len(found_files): return tfh = BytesIO() for full_path in found_files: filename = os.path.basename(full_path) checksum = status[full_path]['hash'] tfh.write(('%s %s\n' % (checksum, filename)).encode('utf-8')) tfh.seek(0) sums_file = os.path.join(root, hash_algorithm + 'sums.asc') cfh = open(sums_file, 'wb') ctx = gpgme.Context() ctx.armor = True ctx.sign(tfh, cfh, gpgme.SIG_MODE_CLEAR) tfh.close() cfh.close() logger.info('Wrote %s' % sums_file)
def encryptContent(self, content, fingerprint): """See IGPGHandler.""" if isinstance(content, unicode): raise TypeError('Content cannot be Unicode.') # setup context ctx = gpgme.Context() ctx.armor = True # setup containers plain = StringIO(content) cipher = StringIO() # retrive gpgme key object try: key = ctx.get_key(fingerprint.encode('ascii'), 0) except gpgme.GpgmeError: return None if not key.can_encrypt: raise ValueError('key %s can not be used for encryption' % fingerprint) # encrypt content ctx.encrypt([key], gpgme.ENCRYPT_ALWAYS_TRUST, plain, cipher) return cipher.getvalue()
def decrypt_content(content, password): """Return the decrypted content or None if failed content and password must be traditional strings. It's up to the caller to encode or decode properly. :content: encrypted data content :password: unicode password to unlock the secret key in question """ if isinstance(password, unicode): raise TypeError('Password cannot be Unicode.') if isinstance(content, unicode): raise TypeError('Content cannot be Unicode.') # setup context ctx = gpgme.Context() ctx.armor = True # setup containers cipher = StringIO(content) plain = StringIO() def passphrase_cb(uid_hint, passphrase_info, prev_was_bad, fd): os.write(fd, '%s\n' % password) ctx.passphrase_cb = passphrase_cb # Do the deecryption. try: ctx.decrypt(cipher, plain) except gpgme.GpgmeError: return None return plain.getvalue()
def test_edit_sign(self): ctx = gpgme.Context() # we set the keylist mode so we can see signatures ctx.keylist_mode = gpgme.KEYLIST_MODE_SIGS ctx.signers = [ctx.get_key('15E7CE9BF1771A4ABC550B31F540A569CB935A42')] key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # check that there are no signatures from 0xCB935A42 for uid in key.uids: sigs = [ sig for sig in uid.signatures if sig.keyid == 'F540A569CB935A42' ] self.assertEqual(len(sigs), 0) gpgme.editutil.edit_sign(ctx, key, check=0) key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # check that there is a signature from 0xCB935A42 on each UID for uid in key.uids: sigs = [ sig for sig in uid.signatures if sig.keyid == 'F540A569CB935A42' ] self.assertEqual(len(sigs), 1)
def generate_signing_key(keyring_path, key_name, key_email, key_expiry): """ Generate a new 2048bit RSA signing key. """ if not os.path.isdir(keyring_path): raise Exception("Keyring path doesn't exist: %s" % keyring_path) key_params = """<GnupgKeyParms format="internal"> Key-Type: RSA Key-Length: 2048 Key-Usage: sign Name-Real: %s Name-Email: %s Expire-Date: %s </GnupgKeyParms> """ % (key_name, key_email, key_expiry) os.environ['GNUPGHOME'] = keyring_path ctx = gpgme.Context() result = ctx.genkey(key_params) key = ctx.get_key(result.fpr, True) [uid] = key.uids return uid
def test_verify_normal(self): signature = StringIO.StringIO( dedent(''' -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.1 (GNU/Linux) owGbwMvMwCTotjv0Q0dM6hLG00JJDM7nNx31SM3JyVcIzy/KSeHqsGdmBQvCVAky pR9hmGfw0qo3bfpWZwun5euYAsUcVkyZMJlhfvkU6UBjD8WF9RfeND05zC/TK+H+ EQA= =HCW0 -----END PGP MESSAGE----- ''')) plaintext = StringIO.StringIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), 'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137685189) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None)
def valid_detached_sig(sig_file, signed_file, gpghome=None): """takes signature , file that was signed and an optional gpghomedir""" if gpgme is None: return False if gpghome: if not os.path.exists(gpghome): return False os.environ['GNUPGHOME'] = gpghome if hasattr(sig_file, 'read'): sig = sig_file else: sig = open(sig_file, 'r') if hasattr(signed_file, 'read'): signed_text = signed_file else: signed_text = open(signed_file, 'r') plaintext = None ctx = gpgme.Context() try: sigs = ctx.verify(sig, signed_text, plaintext) except gpgme.GpgmeError, e: return False
def test_verify_detached(self): signature = StringIO.StringIO( dedent(''' -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQBDz7ReRrtV8IhcZaQRAtuUAJwMiJeS5QPohToxA3+vp+z5c3jr1wCdHhGP hhSTiguzgSYNwKSuV6SLGOM= =dyZS -----END PGP SIGNATURE----- ''')) signed_text = StringIO.StringIO('Hello World\n') ctx = gpgme.Context() sigs = ctx.verify(signature, signed_text, None) self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137685598) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None)
def __init__(self, keyfiles=None): """Initiator.""" if (not keyfiles) or (type(keyfiles) != list): raise ValueError("GPG key file list was not provided") # Setup the internal file pointer to nothing self.fp = None # Testing...probably not needed self._gpghome = tempfile.mkdtemp(prefix="tmp.gpghome") os.environ["GNUPGHOME"] = self._gpghome # Setup GPG context self.ctx = gpgme.Context() # Check keyfiles for k in keyfiles: if not os.path.isfile(k): raise ValueError("GPG key file `%s` could not be found" % k) # open keyfile file pointer fp = open(k, "rb") # import keyfile file pointer self.ctx.import_(fp)
def test_gpg_multiple_homes(tmpdir): """Make sure we can use multiple GPG contexts""" os.environ['GNUPGHOME'] = '/no/such/dir' keysdir = os.path.join(os.path.dirname(__file__), 'keys') for userid in (1, 2): # Create a directory for user's pgp stuff.. gpg_home = str(tmpdir.join('gpg-{0}'.format(userid))) os.makedirs(gpg_home) ctx = gpgme.Context() # We have no keys yet assert len(list(ctx.keylist())) == 0 # Configure GNUPGHOME for this context ctx.set_engine_info(gpgme.PROTOCOL_OpenPGP, None, gpg_home) # Import public keys and check for name in ('key1.pub', 'key2.pub'): with open(os.path.join(keysdir, name), 'rb') as fp: ctx.import_(fp) assert len(list(ctx.keylist())) == 2 assert len(list(ctx.keylist('', True))) == 0 # Import private key and check keyfile = os.path.join(keysdir, 'key{0}.sec'.format(userid)) with open(keyfile, 'r') as fp: ctx.import_(fp) assert len(list(ctx.keylist())) == 2 assert len(list(ctx.keylist('', True))) == 1
def importPublicKey(self, content): """See IGPGHandler.""" assert isinstance(content, str) context = gpgme.Context() context.armor = True newkey = StringIO(content) result = context.import_(newkey) if len(result.imports) == 0: raise GPGKeyNotFoundError(content) # Check the status of all imported keys to see if any of them is # a secret key. We can't rely on result.secret_imported here # because if there's a secret key which is already imported, # result.secret_imported will be 0. for fingerprint, res, status in result.imports: if status & gpgme.IMPORT_SECRET != 0: raise SecretGPGKeyImportDetected( "GPG key '%s' is a secret key." % fingerprint) if len(result.imports) > 1: raise MoreThanOneGPGKeyFound( 'Found %d GPG keys when importing %s' % (len(result.imports), content)) fingerprint, res, status = result.imports[0] key = PymeKey(fingerprint) assert key.exists_in_local_keyring return key
def __init__(self, config_stack): self._config_stack = config_stack try: import gpgme self.context = gpgme.Context() except ImportError, error: pass # can't use verify()
def importSecretKey(self, content): """See `IGPGHandler`.""" assert isinstance(content, str) # Make sure that gpg-agent doesn't interfere. if 'GPG_AGENT_INFO' in os.environ: del os.environ['GPG_AGENT_INFO'] context = gpgme.Context() context.armor = True newkey = StringIO(content) import_result = context.import_(newkey) secret_imports = [ fingerprint for fingerprint, result, status in import_result.imports if status & gpgme.IMPORT_SECRET ] if len(secret_imports) != 1: raise MoreThanOneGPGKeyFound( 'Found %d secret GPG keys when importing %s' % (len(secret_imports), content)) fingerprint, result, status = import_result.imports[0] try: key = context.get_key(fingerprint, True) except gpgme.GpgmeError: return None key = PymeKey.newFromGpgmeKey(key) assert key.exists_in_local_keyring return key
def test_listall(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist()) self.assertTrue(keyids, set(['46BB55F0885C65A4', '2CF46B7FC97E6B0F', 'F540A569CB935A42', '2EF658C987754368']))
def execute(self, log, buildenv, target): if self.node.et.text: fp = self.node.et.text log.printo("transfer gpg key to target: " + fp) os.environ['GNUPGHOME'] = "/var/cache/elbe/gnupg" key = BytesIO() ctx = gpgme.Context() ctx.armor = True ctx.export(fp, key) log.printo(str(key.getvalue())) with open((target.path + '/pub.key'), 'wb') as tkey: tkey.write(key.getvalue()) target.mkdir_p("/var/cache/elbe/gnupg", mode=0700) with target: os.environ['GNUPGHOME'] = target.path + "/var/cache/elbe/gnupg" log.do("gpg --import " + target.path + "/pub.key") log.printo("generate base repo") arch = target.xml.text("project/arch", key="arch") buildenv.rfs.mkdir_p('/tmp/pkgs') with buildenv: cache = get_rpcaptcache(buildenv.rfs, "updated-repo.log", arch) pkglist = cache.get_installed_pkgs() for pkg in pkglist: try: cache.download_binary(pkg.name, '/tmp/pkgs', pkg.installed_version) except ValueError as ve: log.printo("No Package " + pkg.name + "-" + pkg.installed_version) except FetchError as fe: log.printo("Package " + pkg.name + "-" + pkg.installed_version + " could not be downloaded") except TypeError as te: log.printo("Package " + pkg.name + "-" + pkg.installed_version + " missing name or version") r = UpdateRepo(target.xml, target.path + '/var/cache/elbe/repos/base', log) for d in buildenv.rfs.glob('tmp/pkgs/*.deb'): r.includedeb(d, 'main') slist = target.path + '/etc/apt/sources.list.d/base.list' slist_txt = 'deb file:///var/cache/elbe/repos/base ' slist_txt += target.xml.text("/project/suite") slist_txt += " main" with open(slist, 'w') as apt_source: apt_source.write(slist_txt) rmtree(buildenv.rfs.path + '/tmp/pkgs')