def testI01EncryptPublicElGamalDES3ZIP(self): """crypto.cipher: encrypt()/decrypt() ElGamal, DES3 w/ integrity, & ZIP""" key_d = read_test_file(['pgpfiles', 'key', 'DSAELG3.pub.gpg']) keypkt = list_pkts(key_d)[3] # ElGamal encrypting key d = "My secret message." # literal data packet litbody = create_LiteralDataBody(data=d, modified=0, format='b', filename='outfile') litpkt = create_Packet(PKT_LITERAL, litbody._d) # compressed data packet compbody = create_CompressedDataBody(COMP_ZIP, litpkt.rawstr()) comppkt = create_Packet(PKT_COMPRESSED, compbody._d) # session key key = gen_random(_keysize(SYM_DES3)) sespkt = encrypt_public_session(keypkt, key, SYM_DES3) # encrypted data encpkt = encrypt_integrity(SYM_DES3, key, comppkt.rawstr()) # decryption seckey_d = read_test_file( ['pgpfiles', 'key', 'DSAELG3.sec.nopass.gpg']) seckeypkt = list_pkts(seckey_d)[2] clrtxt = decrypt(encpkt, None, sespkt, seckeypkt) # got compressed comppkt_out = list_pkts(clrtxt)[0] # got literal litpkt_out = list_pkts(comppkt_out.body.data)[0] self.assertEqual(d, litpkt_out.body.data) self.assertEqual('outfile', litpkt_out.body.filename) self.assertEqual(0, litpkt_out.body.modified) self.assertEqual('b', litpkt_out.body.format)
def testI01EncryptPublicElGamalDES3ZIP(self): """crypto.cipher: encrypt()/decrypt() ElGamal, DES3 w/ integrity, & ZIP""" key_d = read_test_file(['pgpfiles','key','DSAELG3.pub.gpg']) keypkt = list_pkts(key_d)[3] # ElGamal encrypting key d = "My secret message." # literal data packet litbody = create_LiteralDataBody(data=d, modified=0, format='b', filename='outfile') litpkt = create_Packet(PKT_LITERAL, litbody._d) # compressed data packet compbody = create_CompressedDataBody(COMP_ZIP, litpkt.rawstr()) comppkt = create_Packet(PKT_COMPRESSED, compbody._d) # session key key = gen_random(_keysize(SYM_DES3)) sespkt = encrypt_public_session(keypkt, key, SYM_DES3) # encrypted data encpkt = encrypt_integrity(SYM_DES3, key, comppkt.rawstr()) # decryption seckey_d = read_test_file(['pgpfiles','key','DSAELG3.sec.nopass.gpg']) seckeypkt = list_pkts(seckey_d)[2] clrtxt = decrypt(encpkt, None, sespkt, seckeypkt) # got compressed comppkt_out = list_pkts(clrtxt)[0] # got literal litpkt_out = list_pkts(comppkt_out.body.data)[0] self.assertEqual(d, litpkt_out.body.data) self.assertEqual('outfile', litpkt_out.body.filename) self.assertEqual(0, litpkt_out.body.modified) self.assertEqual('b', litpkt_out.body.format)
def encrypt_symmetric_session(algorithm): """Create a symmetrically-encrypted session key. :Parameters: - `algorithm`: integer symmetric key algorithm constant :Returns: `OpenPGP.packet.SymmetricKeyEncryptedSessionKey.SymmetricKeyEncryptedSessionKey` instance :note: If a local session key is present, `algorithm` denotes the algorithm used to encrypt it. Otherwise, `algorithm` specifies what is used to encrypt the corresponding symmetrically encrypted (possibly integrity protected) data packet. :note: This function does not support locally encrypted session keys - decryption passphrases are "passed through" to the corresponding symmetrically encrypted data. So this function basically just prepares a string-to-key specifier which should be used to create the actual encryption key. """ from openpgp.sap.pkt.Packet import create_Packet from openpgp.sap.pkt.S2K import create_S2K from openpgp.sap.pkt.SymmetricKeyEncryptedSessionKey import create_SymmetricKeyEncryptedSessionKeyBody s2k = create_S2K(salt=gen_random(8)) params = {'alg':algorithm, 's2k':s2k} sesbody = create_SymmetricKeyEncryptedSessionKeyBody(params) return create_Packet(PKT_SYMKEYSESKEY, sesbody._d)
def create_LiteralMsg(literals): """Create a literal message out of a sequence of literal data parameters. :Parameters: - `literals`: list of dictionaries containing literal data parameters (see `Literal keys and values`_) :Returns: `OpenPGP.message.LiteralMsg.LiteralMsg` instance :Exceptions: - `PGPError`: literal message was not created, fix source .. _Literal keys and values: Literal keys and values: - `data`: string of literal data - `modified`: *optional* integer timestamp - `filename`: *optional* string filename - `format`: *optional* 'b' for binary or 't' for text (default binary) """ from openpgp.sap.pkt.Packet import create_Packet from openpgp.sap.pkt.LiteralData import create_LiteralDataBody from openpgp.sap.list import find_literal_msg import time if isinstance(literals, dict): # to accomodate a single dictionary literals = [literals] # yikes litpkts = [] i = 0 for lit in literals: # assume 'data' is present, allow defaults for rest if not lit.has_key('modified'): lit['modified'] = int(time.time()) if not lit.has_key('format'): lit['format'] = 'b' if not lit.has_key('filename'): lit['filename'] = "sap_out_%s" % i litbody = create_LiteralDataBody(lit) litpkts.append(create_Packet(PKT_LITERAL, litbody._d)) litmsg = find_literal_msg(litpkts)[0] if litmsg: return litmsg else: raise Exception("Failed to create literal messge. Fix source.")
def testB01create_Packet(self): "Packet: create_Packet() using PublicKey instance" key_d = read_test_file(['pgpfiles','key','DSAELG1.pub.gpg']) keypkt = LIST.list_pkts(key_d)[0] pkttype = keypkt.tag.type body_d = keypkt.body._d newpkt = create_Packet(pkttype, body_d) # good once-over self.assertEqual(newpkt.tag.type, keypkt.tag.type) self.assertEqual(newpkt.length.size, keypkt.length.size) # ._d could differ self.assertEqual(newpkt.body._d, keypkt.body._d)
def testB01create_Packet(self): "Packet: create_Packet() using PublicKey instance" key_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.pub.gpg']) keypkt = LIST.list_pkts(key_d)[0] pkttype = keypkt.tag.type body_d = keypkt.body._d newpkt = create_Packet(pkttype, body_d) # good once-over self.assertEqual(newpkt.tag.type, keypkt.tag.type) self.assertEqual(newpkt.length.size, keypkt.length.size) # ._d could differ self.assertEqual(newpkt.body._d, keypkt.body._d)
def encrypt_public_session(keypkt, key, symalg): """Create a public-key encrypted session key. :Parameters: - `keypkt`: either an `OpenPGP.packet.PublicKey.PublicKey` (or subclass) instance or encryption passphrase string - `key`: string encryptrion algorithm used for `symalg` - `symalg`: integer symmetric encryption algorithm constant :Returns: `OpenPGP.packet.PublicKeyEncryptedSessionKey.PublicKeyEncryptedSessionKey` instance """ from openpgp.sap.pkt.Packet import create_Packet from openpgp.sap.pkt.PublicKeyEncryptedSessionKey import create_PublicKeyEncryptedSessionKeyBody pubalg = keypkt.body.alg rnd_prefix = [] i = 0 # fixing the "intended length" business to 127 while i <= 63 - len(key): # seems proper, but probably inefficient rnd_byte = gen_random(1) if '\x00' != rnd_byte: rnd_prefix.append(rnd_byte) i += 1 chksum = STN.int2str(STN.checksum(key))[:2] if pubalg in [ASYM_RSA_EOS, ASYM_RSA_E]: key_tup = (keypkt.body.RSA_n.value, keypkt.body.RSA_e.value) elif pubalg in [ASYM_ELGAMAL_EOS, ASYM_ELGAMAL_E]: key_tup = (keypkt.body.ELGAMAL_p.value, keypkt.body.ELGAMAL_g.value, keypkt.body.ELGAMAL_y.value) else: raise NotImplementedError("Unsupported public key algorithm->(%s)." % pubalg) padded_key = ''.join(['\x02', ''.join(rnd_prefix), '\x00', STN.int2str(symalg)[0], key, chksum]) cipher_tup = encrypt_public(pubalg, padded_key, key_tup) sesbody = create_PublicKeyEncryptedSessionKeyBody( keyid=keypkt.body.id, alg=pubalg, mpis=cipher_tup) return create_Packet(PKT_PUBKEYSESKEY, sesbody._d)
def encrypt_integrity(algorithm, key, msg): """Encrypt a message with integrity protection. :Parameters: - `msg`: string cleartext - `algorithm`: integer cipher constant - `key`: string encryption key :Returns: `OpenPGP.packet.SymmetricallyEncryptedIntegrityProtectedData.SymmetricallyEncryptedIntegrityProtectedData` instance :note: It is up to the caller to make sure that `msg` is a valid message string (compressed properly, etc.). :note: Integrity check via SHA-1 is hardcoded. """ import Crypto.Util.randpool as RND from openpgp.sap.pkt.Packet import create_Packet bs = _import_cipher(algorithm).block_size rnd = RND.RandomPool(bs) prefix = rnd.get_bytes(bs) clearstream = StringIO() cipherstream = StringIO() clearstream.write(prefix) clearstream.write(prefix[-2:]) clearstream.write(msg) clearstream.write('\xd3\x14') clearstream.write(sha.new(clearstream.getvalue()).digest()) # hash previous clearstream.seek(0) # again, magic .read() should handle this in crypt_CFB() cipherstream.write('\x01') cipherstream.seek(0, 2) clearstream.seek(0) crypt_CFB(clearstream, cipherstream, algorithm, key, None, 'encrypt') cipherstream.seek(0) ciphertext = cipherstream.read() return create_Packet(PKT_SYMENCINTDATA, ciphertext)
sigtup = sign_ElGamal(ctx_hash, keytup) elif ASYM_DSA == keyalg: keytup = signer.body.DSA_y.value, signer.body.DSA_g.value, signer.body.DSA_p.value, signer.body.DSA_q.value, seckey sigtup = sign_DSA(ctx_hash, keytup) else: raise NotImplementedError("Public key alg->(%s) is not supported." % keyalg) kwords.update({'version':version, 'sigtype':sigtype, 'alg_pubkey':keyalg, 'alg_hash':hashalg, 'hash_frag':ctx_hash[:2], 'signature':[create_MPI(sigval) for sigval in sigtup]}) body = create_SignatureBody(**kwords) return create_Packet(PKT_SIGNATURE, body._d) def sign_DSA(msg, key_tuple, k=None): """Create a DSA signature. :Parameters: - `msg`: string of data signature applies to - `key_tuple`: tuple of DSA integers (y, g, p, q, x) (see `DSA tuple`_) - `k`: random integer 2 < k < q (automatically generated by default) :Returns: tuple (integer, integer) DSA signature values (r, s) .. _DSA tuple: