def __testC05CreateArmoredClearSigned(self): "armory: apply_armor() clearsigned message" gpg_d = read_test_file(['pgpfiles', 'sig', 'sig.DSAELG1.onepass.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg, clearsign=True) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('SIGNED MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def __testC05CreateArmoredClearSigned(self): "armory: apply_armor() clearsigned message" gpg_d = read_test_file(['pgpfiles','sig','sig.DSAELG1.onepass.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg, clearsign=True) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('SIGNED MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testC04CreateArmoredSigned(self): "armory: apply_armor() signed, uncompressed message" gpg_d = read_test_file(['pgpfiles','sig','sig.DSAELG1.onepass.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testC04CreateArmoredSigned(self): "armory: apply_armor() signed, uncompressed message" gpg_d = read_test_file(['pgpfiles', 'sig', 'sig.DSAELG1.onepass.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testC01CreateArmoredPublicKey(self): "armory: apply_armor() DSA/ElGamal public key" gpg_d = read_test_file(['pgpfiles','key','DSAELG1.pub.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('PUBLIC KEY BLOCK', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testC01CreateArmoredPublicKey(self): "armory: apply_armor() DSA/ElGamal public key" gpg_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.pub.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('PUBLIC KEY BLOCK', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testB03MultiplePreferencesSameValues(self): """sap.api: find_key_prefs() two keys, same values""" key1_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.pub.gpg']) keymsg1 = list_msgs(list_pkts(key1_d))[0] key2_d = read_test_file(['pgpfiles', 'key', 'RSA1.pub.gpg']) keymsg2 = list_msgs(list_pkts(key2_d))[0] preferred = find_key_prefs([keymsg1, keymsg2]) self.assertEqual(preferred['sym'], [9, 8, 7, 3, 2]) self.assertEqual(preferred['hash'], [2, 3]) self.assertEqual(preferred['comp'], [2, 1])
def testF01ElGamal(self): """crypto.cipher: decrypt_public() ElGamal-encrypted session key""" #encmsg_d = read_test_file(['pgpfiles','enc','pub.elg.aes256.clrtxt.gpg']) encmsg_d = read_test_file( ['pgpfiles', 'enc', 'pub.elg.cast.clrtxt.gpg']) encmsg = list_msgs(list_pkts(encmsg_d))[0] seskeypkt = encmsg.targets[0] # target = session key # get target secret key (in this case, a subkey) keymsg_d = read_test_file( ['pgpfiles', 'key', 'DSAELG1.sec.nopass.gpg']) keymsg = list_msgs(list_pkts(keymsg_d))[0] for block in keymsg._b_subkeys.list(): subkey = block.leader if seskeypkt.body.keyid == subkey.body.id: break # leave with the appropriate subkey # I know the target in question is an ElGamal key key_tuple = (subkey.body.ELGAMAL_p.value, subkey.body.ELGAMAL_x.value) cipher_tuple = (seskeypkt.body.ELGAMAL_gk_modp.value, seskeypkt.body.ELGAMAL_myk_modp.value) # retrieving the PKCS, etc., padded session key padded_message = decrypt_public(seskeypkt.body.alg_pubkey, key_tuple, cipher_tuple) # Rules from rfc 2437 9.1.2.2: # 1. Padding starts with 0x02. # 2. Padding continues with >= 8 octets non-zero gibberish. # 3. Gibberish concludes with 0x00. # 4. Remaining data is the message. if '\x02' == padded_message[0]: idx = padded_message.find('\x00') if -1 != idx and 8 <= idx: message = padded_message[idx + 1:] chksum = str2int(message[-2:]) ciphertype = str2int(message[0]) key = message[1:len(message) - 2] i = 0 for e in key: i += str2int(e) # TODO check chksum cleartext = decrypt_symmetric(ciphertype, key, encmsg.encrypted.body.data) else: errmsg = "Misplaced \\x00 in session key padding, located at index->(%s)" % idx else: errmsg = "Session key padding must start with \\x02, received->()" % hex( ord(padded_message[0])) cleartext = cleartext[10:] # ditching the prefix + 2 # result is a compressed message.. compressedmsg = list_msgs(list_pkts(cleartext))[0] newmsgs = list_msgs(list_pkts(compressedmsg.compressed.body.data)) # ..with only one literal data packet literal_data = newmsgs[0].literals[0].body.data # compare against original file clrtxt = read_test_file(['pgpfiles', 'cleartext.txt']) self.assertEqual(literal_data, clrtxt)
def testC02CreateArmoredEncrypted(self): "armory: apply_armor() ElGamal/CAST encrypted message" gpg_d = read_test_file(['pgpfiles','enc','pub.elg.aes256.clrtxt.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) #f = file('pgpfiles/enc/sap.pub.elg.aes256.clrtxt.asc', 'w') #f.write(armored_d) #f.close() armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testC02CreateArmoredEncrypted(self): "armory: apply_armor() ElGamal/CAST encrypted message" gpg_d = read_test_file( ['pgpfiles', 'enc', 'pub.elg.aes256.clrtxt.gpg']) msg = list_msgs(list_pkts(gpg_d))[0] armored_d = apply_armor(msg) #f = file('pgpfiles/enc/sap.pub.elg.aes256.clrtxt.asc', 'w') #f.write(armored_d) #f.close() armored = list_armored(armored_d)[0] newmsg = list_msgs(list_pkts(armored.data))[0] self.assertEqual('MESSAGE', armored.title) self.assertEqual(msg.rawstr(), newmsg.rawstr())
def testB04MultiplePreferencesDifferentValues(self): """sap.api: find_key_prefs() two keys, different values""" key1_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.pub.gpg']) # sym[9, 8, 7, 3, 2], hash[2, 3], comp[2, 1] keymsg1 = list_msgs(list_pkts(key1_d))[0] key2_d = read_test_file( ['pgpfiles', 'interop', 'pgp8.0.2', 'key.pgp8.0.2.DHDSS1.pub.asc']) d = list_armored(key2_d)[0].data # sym[9, 8, 7, 3, 2, 10], empty hash, empty comp keymsg2 = list_msgs(list_pkts(d))[0] preferred = find_key_prefs([keymsg1, keymsg2]) self.assertEqual(preferred['sym'], [9, 8, 7, 3, 2]) self.assertEqual(preferred['hash'], []) self.assertEqual(preferred['comp'], [])
def testF01ElGamal(self): """crypto.cipher: decrypt_public() ElGamal-encrypted session key""" #encmsg_d = read_test_file(['pgpfiles','enc','pub.elg.aes256.clrtxt.gpg']) encmsg_d = read_test_file(['pgpfiles','enc','pub.elg.cast.clrtxt.gpg']) encmsg = list_msgs(list_pkts(encmsg_d))[0] seskeypkt = encmsg.targets[0] # target = session key # get target secret key (in this case, a subkey) keymsg_d = read_test_file(['pgpfiles','key','DSAELG1.sec.nopass.gpg']) keymsg = list_msgs(list_pkts(keymsg_d))[0] for block in keymsg._b_subkeys.list(): subkey = block.leader if seskeypkt.body.keyid == subkey.body.id: break # leave with the appropriate subkey # I know the target in question is an ElGamal key key_tuple = (subkey.body.ELGAMAL_p.value, subkey.body.ELGAMAL_x.value) cipher_tuple = (seskeypkt.body.ELGAMAL_gk_modp.value, seskeypkt.body.ELGAMAL_myk_modp.value) # retrieving the PKCS, etc., padded session key padded_message = decrypt_public(seskeypkt.body.alg_pubkey, key_tuple, cipher_tuple) # Rules from rfc 2437 9.1.2.2: # 1. Padding starts with 0x02. # 2. Padding continues with >= 8 octets non-zero gibberish. # 3. Gibberish concludes with 0x00. # 4. Remaining data is the message. if '\x02' == padded_message[0]: idx = padded_message.find('\x00') if -1 != idx and 8 <= idx: message = padded_message[idx+1:] chksum = str2int(message[-2:]) ciphertype = str2int(message[0]) key = message[1:len(message)-2] i = 0 for e in key: i += str2int(e) # TODO check chksum cleartext = decrypt_symmetric(ciphertype, key, encmsg.encrypted.body.data) else: errmsg = "Misplaced \\x00 in session key padding, located at index->(%s)" % idx else: errmsg = "Session key padding must start with \\x02, received->()" % hex(ord(padded_message[0])) cleartext = cleartext[10:] # ditching the prefix + 2 # result is a compressed message.. compressedmsg = list_msgs(list_pkts(cleartext))[0] newmsgs = list_msgs(list_pkts(compressedmsg.compressed.body.data)) # ..with only one literal data packet literal_data = newmsgs[0].literals[0].body.data # compare against original file clrtxt = read_test_file(['pgpfiles','cleartext.txt']) self.assertEqual(literal_data, clrtxt)
def testB11NestedNormalSigsLeftovers(self): """message.list_msgs: nested normal signatures with leftovers""" sig_msgs = self.signest_normal for sig_msg in sig_msgs: sig_msg[1].append(EMPTY.sig) # add lone signature packet msgs = list_msgs(sig_msg[1]) self.assertEqual(sig_msg[0], msgs[0].type)
def verify_userid(keydata): keymsg = list_msgs(list_pkts(keydata))[0] userid = keymsg._b_userids[0].leader # first user id useridsig = keymsg._b_userids[0].local_bindings[ 0] # first applicable signature pubkey = keymsg._b_primary.leader return verify(useridsig, userid, pubkey)
def testA01PublicKeyAttributes(self): "PublicKeyMsg: attribute order check" key_d = read_test_file(['pgpfiles','key','DSAELG2.subkeyrevoc.gpg']) pkts = list_pkts(key_d) # for sequence test keymsg = list_msgs(pkts)[0] # check type self.assertEqual(keymsg.type, MSG_PUBLICKEY) # user ids self.assertEqual(keymsg._b_userids[0].leader.body.value, 'test2 (test many subkeys) <[email protected]>') self.assertEqual(keymsg._b_userids[0], keymsg._b_userids['test2 (test many subkeys) <[email protected]>']) # account for all the subkey IDs, *ordering is important* known_subkey_ids = ['1BEA996EB8246578', 'A4E57E4D8A3BAAE8', 'B45D57C94A595CEE', '90AFB828686B6E9A', '52E7E945372C2D26', 'A6EA514C4F7232B2'] self.assertEqual(known_subkey_ids, keymsg._b_subkeys.keylist) # check that block list matches up with dictionary values for i in enumerate(keymsg._b_subkeys.keylist): self.assertEqual(keymsg._b_subkeys[i[0]], keymsg._b_subkeys[i[1]]) # check that primary key is represented self.assertEqual('6246EF319AC13CFC', keymsg.primary_id) self.assertEqual('6246EF319AC13CFC', keymsg._b_primary.leader.body.id) # user ID access good_uid = "test2 (test many subkeys) <[email protected]>" test_uid = keymsg._b_userids[0].leader.body.value self.assertEqual(good_uid, test_uid)
def testA01PublicKeyAttributes(self): "PublicKeyMsg: attribute order check" key_d = read_test_file(['pgpfiles', 'key', 'DSAELG2.subkeyrevoc.gpg']) pkts = list_pkts(key_d) # for sequence test keymsg = list_msgs(pkts)[0] # check type self.assertEqual(keymsg.type, MSG_PUBLICKEY) # user ids self.assertEqual(keymsg._b_userids[0].leader.body.value, 'test2 (test many subkeys) <[email protected]>') self.assertEqual( keymsg._b_userids[0], keymsg._b_userids['test2 (test many subkeys) <[email protected]>']) # account for all the subkey IDs, *ordering is important* known_subkey_ids = [ '1BEA996EB8246578', 'A4E57E4D8A3BAAE8', 'B45D57C94A595CEE', '90AFB828686B6E9A', '52E7E945372C2D26', 'A6EA514C4F7232B2' ] self.assertEqual(known_subkey_ids, keymsg._b_subkeys.keylist) # check that block list matches up with dictionary values for i in enumerate(keymsg._b_subkeys.keylist): self.assertEqual(keymsg._b_subkeys[i[0]], keymsg._b_subkeys[i[1]]) # check that primary key is represented self.assertEqual('6246EF319AC13CFC', keymsg.primary_id) self.assertEqual('6246EF319AC13CFC', keymsg._b_primary.leader.body.id) # user ID access good_uid = "test2 (test many subkeys) <[email protected]>" test_uid = keymsg._b_userids[0].leader.body.value self.assertEqual(good_uid, test_uid)
def verify_subkey(keydata): keymsg = list_msgs(list_pkts(keydata))[0] subkey = keymsg._b_subkeys[0].leader # first subkey subkeysig = keymsg._b_subkeys[0].local_bindings[ 0] # first applicable signature pubkey = keymsg._b_primary.leader # public key return verify(subkeysig, subkey, pubkey)
def testD07CertificationRevocation(self): "crypto.signature: verify() certification revocation" key_d = read_test_file(['pgpfiles', 'key', 'DSAELG2.revoked_uid.gpg']) pkts = list_pkts(key_d) keymsg = list_msgs(pkts)[0] primary_key, uid, revoker = pkts[0], pkts[3], pkts[4] verified = verify(revoker, uid, primary_key) self.assertEqual(True, verify(revoker, uid, primary_key))
def testD07CertificationRevocation(self): "crypto.signature: verify() certification revocation" key_d = read_test_file(['pgpfiles','key','DSAELG2.revoked_uid.gpg']) pkts = list_pkts(key_d) keymsg = list_msgs(pkts)[0] primary_key, uid, revoker = pkts[0], pkts[3], pkts[4] verified = verify(revoker, uid, primary_key) self.assertEqual(True, verify(revoker, uid, primary_key))
def testB02Preferences(self): """sap.api: find_key_prefs() single key""" key_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.pub.gpg']) keymsg = list_msgs(list_pkts(key_d))[0] preferred = find_key_prefs([keymsg]) self.assertEqual(preferred['sym'], [9, 8, 7, 3, 2]) self.assertEqual(preferred['hash'], [2, 3]) self.assertEqual(preferred['comp'], [2, 1])
def testD03aDSAv4UIDPrivate(self): "crypto.signature: verify() private key user ID v4 DSA" msgs = list_msgs(list_pkts(dsaseckey_d)) keymsg = msgs[0] uid = keymsg._b_userids[0].leader # first user id sig = keymsg._b_userids[0].local_bindings[0] # first applicable signature key = keymsg._b_primary.leader # public key self.assertEqual(1, verify(sig, uid, key))
def testD04aDSAv4SubkeyPrivate(self): "crypto.signature: verify() pivate key subkey binding v4 DSA" msgs = list_msgs(list_pkts(dsaseckey_d)) keymsg = msgs[0] subkey = keymsg._b_subkeys[0].leader # first subkey subkeysig = keymsg._b_subkeys[0].local_bindings[0] # first applicable signature pubkey = keymsg._b_primary.leader # public key self.assertEqual(1, verify(subkeysig, subkey, pubkey))
def testB07ListMultiple_1(self): """message.list_msgs: multiple messages, nothing leftover""" enc_msg = self.single_empty_encrypted_msgs[2] sig_msg = self.single_empty_signed_msgs[1] l = [] msgs = list_msgs(enc_msg[1] + sig_msg[1], leftover=l) self.assertEqual(msgs[0].type, enc_msg[0]) self.assertEqual(msgs[1].type, sig_msg[0]) self.assertEqual(len(l), 0) # nothing leftover
def testD06SubkeyRevocation(self): "crypto.signature: verify() subkey revocation" d = read_test_file(['pgpfiles', 'key', 'DSAELG2.subkeyrevoc.gpg']) keymsg = list_msgs(list_pkts(d))[0] revblock = keymsg._b_subkeys['90AFB828686B6E9A'] # known revoked block key = keymsg._b_primary.leader sig = revblock.local_bindings[0] subkey = revblock.leader self.assertEqual(1, verify(sig, subkey, key))
def testD04aDSAv4SubkeyPrivate(self): "crypto.signature: verify() pivate key subkey binding v4 DSA" msgs = list_msgs(list_pkts(dsaseckey_d)) keymsg = msgs[0] subkey = keymsg._b_subkeys[0].leader # first subkey subkeysig = keymsg._b_subkeys[0].local_bindings[ 0] # first applicable signature pubkey = keymsg._b_primary.leader # public key self.assertEqual(1, verify(subkeysig, subkey, pubkey))
def testD03aDSAv4UIDPrivate(self): "crypto.signature: verify() private key user ID v4 DSA" msgs = list_msgs(list_pkts(dsaseckey_d)) keymsg = msgs[0] uid = keymsg._b_userids[0].leader # first user id sig = keymsg._b_userids[0].local_bindings[ 0] # first applicable signature key = keymsg._b_primary.leader # public key self.assertEqual(1, verify(sig, uid, key))
def testD06SubkeyRevocation(self): "crypto.signature: verify() subkey revocation" d = read_test_file(['pgpfiles','key','DSAELG2.subkeyrevoc.gpg']) keymsg = list_msgs(list_pkts(d))[0] revblock = keymsg._b_subkeys['90AFB828686B6E9A'] # known revoked block key = keymsg._b_primary.leader sig = revblock.local_bindings[0] subkey = revblock.leader self.assertEqual(1, verify(sig, subkey, key))
def testA03PublicKeyEncryptedMsg(self): """message.EncryptedMsg: single public key target EncryptedMsg""" msg_d = read_test_file(['pgpfiles','enc','pub.elg.aes256.clrtxt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(1, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(1, encmsg.targets[0].tag.type) self.assertEqual(95, len(encmsg.encrypted.body.data))
def testG05Decrypt5(self): """crypto.cipher: decrypt() symmetric (CAST) compressed""" enc_d = read_test_file(['pgpfiles','enc','sym.cast.cleartext.txt.gpg']) clr_d = read_test_file(['pgpfiles','cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' msg_d = decrypt(encpkt, passphrase, sespkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testA01PublicKeyEncryptedMsg(self): """(interop) message.EncryptedMsg: PGP 6.5.3 single public key target EncryptedMsg""" msg_d = read_test_file(['pgpfiles','interop','pgp6.5.3','RSA1','encrypted.cleartext.notepad.pgp6.5.3.RSA1.pgp']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(0, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(1, encmsg.targets[0].tag.type) self.assertEqual(85, len(encmsg.encrypted.body.data))
def testA02ProtectedSingleTargetCAST5(self): """message.EncryptedMsg: single symmetric target protected (MDC) EncryptedMsg""" msg_d = read_test_file(['pgpfiles','enc','mdc.14.212.136.clrtxt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(1, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(3, encmsg.targets[0].tag.type) self.assertEqual(80, len(encmsg.encrypted.body.data))
def testA01SymmetricSingleTargetCAST5(self): """message.EncryptedMsg: single symmetric target EncryptedMsg""" msg_d = read_test_file(['pgpfiles','enc','sym.cast.cleartext.txt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(0, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(3, encmsg.targets[0].tag.type) self.assertEqual(59, len(encmsg.encrypted.body.data))
def testG05Decrypt5(self): """crypto.cipher: decrypt() symmetric (CAST) compressed""" enc_d = read_test_file( ['pgpfiles', 'enc', 'sym.cast.cleartext.txt.gpg']) clr_d = read_test_file(['pgpfiles', 'cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' msg_d = decrypt(encpkt, passphrase, sespkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testA02ProtectedSingleTargetCAST5(self): """message.EncryptedMsg: single symmetric target protected (MDC) EncryptedMsg""" msg_d = read_test_file( ['pgpfiles', 'enc', 'mdc.14.212.136.clrtxt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(1, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(3, encmsg.targets[0].tag.type) self.assertEqual(80, len(encmsg.encrypted.body.data))
def testA01SymmetricSingleTargetCAST5(self): """message.EncryptedMsg: single symmetric target EncryptedMsg""" msg_d = read_test_file( ['pgpfiles', 'enc', 'sym.cast.cleartext.txt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(0, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(3, encmsg.targets[0].tag.type) self.assertEqual(59, len(encmsg.encrypted.body.data))
def testA03PublicKeyEncryptedMsg(self): """message.EncryptedMsg: single public key target EncryptedMsg""" msg_d = read_test_file( ['pgpfiles', 'enc', 'pub.elg.aes256.clrtxt.gpg']) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(1, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(1, encmsg.targets[0].tag.type) self.assertEqual(95, len(encmsg.encrypted.body.data))
def testG03Decrypt3(self): """crypto.cipher: decrypt() v3 public (RSA nopass) 3DES compressed""" enc_d = read_test_file(['pgpfiles','enc','pub.pgp653rsa.clrtxt.gpg']) key_d = read_test_file(['pgpfiles','key','pgp653rsa.sec.nopass.gpg']) clr_d = read_test_file(['pgpfiles','cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' sespkt, encpkt = list_pkts(enc_d) keypkt = list_pkts(key_d)[0] msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testG03Decrypt3(self): """crypto.cipher: decrypt() v3 public (RSA nopass) 3DES compressed""" enc_d = read_test_file(['pgpfiles', 'enc', 'pub.pgp653rsa.clrtxt.gpg']) key_d = read_test_file(['pgpfiles', 'key', 'pgp653rsa.sec.nopass.gpg']) clr_d = read_test_file(['pgpfiles', 'cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' sespkt, encpkt = list_pkts(enc_d) keypkt = list_pkts(key_d)[0] msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testA01PublicKeyEncryptedMsg(self): """(interop) message.EncryptedMsg: PGP 6.5.3 single public key target EncryptedMsg""" msg_d = read_test_file([ 'pgpfiles', 'interop', 'pgp6.5.3', 'RSA1', 'encrypted.cleartext.notepad.pgp6.5.3.RSA1.pgp' ]) msgs = list_msgs(list_pkts(msg_d)) encmsg = msgs[0] self.assertEqual(MSG_ENCRYPTED, encmsg.type) self.assertEqual(0, encmsg.integrity) self.assertEqual(1, len(encmsg.targets)) self.assertEqual(1, encmsg.targets[0].tag.type) self.assertEqual(85, len(encmsg.encrypted.body.data))
def testG01Decrypt1(self): """crypto.cipher: decrypt() v4 public (ElGamal) MDC CAST5 compressed""" # This message is known to have a compressed packet containing a literal # packet containing the text from cleartext.txt. enc_d = read_test_file(['pgpfiles', 'enc', 'pub.elg.cast.clrtxt.gpg']) key_d = read_test_file(['pgpfiles', 'key', 'DSAELG1.sec.gpg']) clr_d = read_test_file(['pgpfiles', 'cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) keypkt = list_pkts(key_d)[3] # first encryption subkey (known) passphrase = 'test' msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testC07SubkeyRevocation(self): "crypto.signature: verify_DSA() subkey revocation by hand" d = read_test_file(['pgpfiles','key','DSAELG2.subkeyrevoc.gpg']) keymsg = list_msgs(list_pkts(d))[0] revblock = keymsg._b_subkeys['90AFB828686B6E9A'] # known revoked block key = keymsg._b_primary.leader sig = revblock.local_bindings[0] subkey = revblock.leader l1 = int2quadoct(len(key.body._d))[-2:] l2 = int2quadoct(len(subkey.body._d))[-2:] context = sha.new('\x99'+l1+key.body._d+'\x99'+l2+subkey.body._d+sig.body.hashed_data).digest() sigtup = (sig.body.DSA_r.value, sig.body.DSA_s.value) keytup = (key.body.DSA_y.value, key.body.DSA_g.value, key.body.DSA_p.value, key.body.DSA_q.value) self.assertEqual(1, verify_DSA(context, sigtup, keytup))
def testG02Decrypt2(self): """crypto.cipher: decrypt() v4 public (ElGamal) MDC AES256 compressed""" # This message is known to have a compressed packet containing a literal # packet containing the text from cleartext.txt. enc_d = read_test_file(['pgpfiles','enc','pub.elg.aes256.clrtxt.gpg']) key_d = read_test_file(['pgpfiles','key','DSAELG1.sec.gpg']) clr_d = read_test_file(['pgpfiles','cleartext.txt']) sespkt, encpkt = list_pkts(enc_d) keypkt = list_pkts(key_d)[3] # first encryption subkey (known) passphrase = 'test' msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testB06ListLeftovers(self): """message.list_msgs: find packet leftovers""" for msgtype in [self.single_empty_literal_msgs, self.single_empty_compressed_msgs, self.single_empty_encrypted_msgs, self.single_empty_signed_msgs]: for msg in msgtype: msg[1].append(EMPTY.uid) msg[1].append(EMPTY.uid) l = [] msgs = list_msgs(msg[1], leftover=l) self.assertEqual(msg[0], msgs[0].type) self.assertEqual(l[0].tag.type, EMPTY.uid.tag.type) self.assertEqual(l[1].tag.type, EMPTY.uid.tag.type) self.assertEqual(len(l), 2)
def testG04Decrypt4(self): """crypto.cipher: decrypt() v3 public (RSA) 3DES compressed""" prefix = ['pgpfiles','interop','pgp6.5.3','RSA1'] enc_d = read_test_file(prefix+['encrypted.cleartext.notepad.pgp6.5.3.RSA1.pgp']) key_d = read_test_file(prefix+['key.pgp6.5.3.RSA1.sec.asc']) clr_d = read_test_file(prefix+['cleartext.notepad.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' # first (totally detached) armored block has [secret key pkt, uid pkt] arms = list_armored(key_d) keypkt = list_pkts(arms[0].data)[0] msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def testB06ListLeftovers(self): """message.list_msgs: find packet leftovers""" for msgtype in [ self.single_empty_literal_msgs, self.single_empty_compressed_msgs, self.single_empty_encrypted_msgs, self.single_empty_signed_msgs ]: for msg in msgtype: msg[1].append(EMPTY.uid) msg[1].append(EMPTY.uid) l = [] msgs = list_msgs(msg[1], leftover=l) self.assertEqual(msg[0], msgs[0].type) self.assertEqual(l[0].tag.type, EMPTY.uid.tag.type) self.assertEqual(l[1].tag.type, EMPTY.uid.tag.type) self.assertEqual(len(l), 2)
def testC07SubkeyRevocation(self): "crypto.signature: verify_DSA() subkey revocation by hand" d = read_test_file(['pgpfiles', 'key', 'DSAELG2.subkeyrevoc.gpg']) keymsg = list_msgs(list_pkts(d))[0] revblock = keymsg._b_subkeys['90AFB828686B6E9A'] # known revoked block key = keymsg._b_primary.leader sig = revblock.local_bindings[0] subkey = revblock.leader l1 = int2quadoct(len(key.body._d))[-2:] l2 = int2quadoct(len(subkey.body._d))[-2:] context = sha.new('\x99' + l1 + key.body._d + '\x99' + l2 + subkey.body._d + sig.body.hashed_data).digest() sigtup = (sig.body.DSA_r.value, sig.body.DSA_s.value) keytup = (key.body.DSA_y.value, key.body.DSA_g.value, key.body.DSA_p.value, key.body.DSA_q.value) self.assertEqual(1, verify_DSA(context, sigtup, keytup))
def testG04Decrypt4(self): """crypto.cipher: decrypt() v3 public (RSA) 3DES compressed""" prefix = ['pgpfiles', 'interop', 'pgp6.5.3', 'RSA1'] enc_d = read_test_file( prefix + ['encrypted.cleartext.notepad.pgp6.5.3.RSA1.pgp']) key_d = read_test_file(prefix + ['key.pgp6.5.3.RSA1.sec.asc']) clr_d = read_test_file(prefix + ['cleartext.notepad.txt']) sespkt, encpkt = list_pkts(enc_d) passphrase = 'test' # first (totally detached) armored block has [secret key pkt, uid pkt] arms = list_armored(key_d) keypkt = list_pkts(arms[0].data)[0] msg_d = decrypt(encpkt, passphrase, sespkt, keypkt) compmsg = list_msgs(list_pkts(msg_d))[0] litpkt = list_pkts(compmsg.compressed.body.data)[0] self.assertEqual(clr_d, litpkt.body.data)
def slice_pkt_str(msg_d, slice_d): """Return a packet slice from a string of OpenPGP data. :Parameters: - `msg_d`: string OpenPGP data - `slice_d`: string slice notation (see `Slice syntax`_) :Returns: list of sliced items (message or packet instances) .. _Slice syntax: Slice syntax The slice string looks like ``M[x:y:z]`` where ``M`` is either an integer message index or the (capital) letter "L" and ``[x:y:z]`` is a normal Python slice. An integer value ``M`` specifies the index of a message in the list of messages to slice packets from. The value "L" is used to take a slice from the list of leftover packets. :note: This uses `eval()`, so tread lightly. :note: If you shake it, it will break. Play nice. :todo: Add deep msg slicing (ex.signed contains literal - 0[0][1:3]). """ if looks_armored(msg_d): msg_d = ''.join([a.data for a in list_armored(msg_d)]) l = [] players = list_msgs(list_pkts(msg_d), leftover=l) if 'L' == slice_d[0]: items = l saplog.info("Slicing leftover packets (%s total)." % len(items)) else: msg_idx = int(slice_d[0]) items = players[msg_idx].seq() saplog.info("Slicing message %s of %s." % (msg_idx, len(players)-1)) pkt_slice = eval("items%s" % slice_d[1:]) if isinstance(pkt_slice, list): return pkt_slice else: return [pkt_slice]
def slice_pkt_str(msg_d, slice_d): """Return a packet slice from a string of OpenPGP data. :Parameters: - `msg_d`: string OpenPGP data - `slice_d`: string slice notation (see `Slice syntax`_) :Returns: list of sliced items (message or packet instances) .. _Slice syntax: Slice syntax The slice string looks like ``M[x:y:z]`` where ``M`` is either an integer message index or the (capital) letter "L" and ``[x:y:z]`` is a normal Python slice. An integer value ``M`` specifies the index of a message in the list of messages to slice packets from. The value "L" is used to take a slice from the list of leftover packets. :note: This uses `eval()`, so tread lightly. :note: If you shake it, it will break. Play nice. :todo: Add deep msg slicing (ex.signed contains literal - 0[0][1:3]). """ if looks_armored(msg_d): msg_d = ''.join([a.data for a in list_armored(msg_d)]) l = [] players = list_msgs(list_pkts(msg_d), leftover=l) if 'L' == slice_d[0]: items = l saplog.info("Slicing leftover packets (%s total)." % len(items)) else: msg_idx = int(slice_d[0]) items = players[msg_idx].seq() saplog.info("Slicing message %s of %s." % (msg_idx, len(players) - 1)) pkt_slice = eval("items%s" % slice_d[1:]) if isinstance(pkt_slice, list): return pkt_slice else: return [pkt_slice]
def testB09NestedOnePassSigsLeftovers(self): """message.list_msgs: nested one-pass signatures with leftovers""" sig_msgs = self.signest_onepass for sig_msg in sig_msgs: sig_msg[1].append(EMPTY.sig) # add lone signature packet l = [] msgs = list_msgs(sig_msg[1], leftover=l) # we have 4 nested onepass sigs mainsig = msgs[0] self.assertEqual(mainsig.msg.type, MSG_SIGNED) self.assertEqual(mainsig.msg.msg.type, MSG_SIGNED) self.assertEqual(mainsig.msg.msg.msg.type, MSG_SIGNED) self.assertEqual(mainsig.msg.msg.msg.msg.type, MSG_ENCRYPTED) self.assertEqual(sig_msg[0], mainsig.type) # identify lone signature packet as a leftover #self.assertEqual(msgs[1][0].tag.type, EMPTY.sig.tag.type) self.assertEqual(l[0].tag.type, EMPTY.sig.tag.type)
def show_msgs(d, m_idx=0): """Show a synopsis of the packets in a message. :Parameters: - `d`: variable OpenPGP data - may be a string contaning OpenPGP packets, a list of OpenPGP messages, or a single OpenPGP message instance - `m_idx`: counter used to keep track of indentation - should just leave it alone :Returns: string of message information found in `d` Data `d` can either be an unbroken string of native OpenPGP data or normal text with one or more ASCII-armored blocks (but not both). """ from openpgp.sap.msg.Msg import Msg l = [] if isinstance(d, str): if looks_armored(d): armored = list_armored(d) d = ''.join([a.data for a in armored ]) # we may have many armored instances msgs = list_msgs(list_pkts(d), leftover=l) elif isinstance(d, list): # assume a list of messages msgs = d l = None elif isinstance(d, MSG.Msg.Msg): msgs = [d] l = None r = [] # report, lines of msg/pkt info tab = ' ' if 0 == m_idx: m_tab = '' else: m_tab = tab for m in msgs: r.append("%s%s %s" % (m_tab, m_idx, TXT.msg_msg(m.type))) i_idx = 0 i_list = [] for i in m.seq(): if isinstance(i, Msg): r.append(show_msgs(i.rawstr(), i_idx)) else: # assume packet r.append("%s%s %s" % (m_tab + tab, i_idx, show_simple_packet(i))) i_idx += 1 m_idx += 1 if l: r.append("Leftover (non-message) packets") for p in l: r.append(" %s" % show_simple_packet(p)) return linesep.join(r)
def testBO5ListPublicKey(self): """message.list_msgs: public key message""" pkts = list_pkts(dsapubkey_d) msgs = list_msgs(pkts) self.assertEqual(MSG_PUBLICKEY, msgs[0].type)
def testB08NestedOnePassSigs(self): """message.list_msgs: nested one-pass signatures""" sig_msgs = self.signest_onepass for sig_msg in sig_msgs: msgs = list_msgs(sig_msg[1]) self.assertEqual(sig_msg[0], msgs[0].type)
def testB10NestedNormalSigs(self): """message.list_msgs: nested normal signatures""" sig_msgs = self.signest_normal for sig_msg in sig_msgs: msgs = list_msgs(sig_msg[1]) self.assertEqual(sig_msg[0], msgs[0].type)
def testA02CatchUnboundSubblocks(self): "PublicKeyMsg: dismiss unbound private encryption key" key_d = read_test_file(['pgpfiles','key','DSAELG3.sec.nopass.gpg']) keymsg = list_msgs(list_pkts(key_d))[0] self.assertEqual(1, len(keymsg.seq())) # only one packet exists.. keymsg._b_primary.leader.body.id # ..make sure it's the signing primary
def testD02RSAPGPSig(self): "crypto.signature: verify() v3 RSA One-Pass" keypkt = list_pkts(rsapubkey_d)[0] msgs = list_msgs(list_pkts(rsasig_d)) sigmsg = msgs[0] self.assertEqual(1, verify(sigmsg.sigs[0], sigmsg.msg, keypkt))
def testB1gpgpubkey(self): "armory: retrieve armored public key message (GnuPG 1.2.2)" apkey = list_armored(gpgpubkey)[0] msgs = list_msgs(list_pkts(apkey.data)) self.assertEqual(MSG_PUBLICKEY, msgs[0].type)