def _known_values(folder='.'): """Return tmp files with known keys, data, signature for testing. This is a WEAK key, 1024 bits, for testing ONLY. """ bits = '1024' pub, priv, pphr = GenRSA().demo_rsa_keys(folder) kwnSig0p9p8 = ( # openssl 0.9.8r "dNF9IudjTjZ9sxO5P07Kal9FkY7hCRJCyn7IbebJtcEoVOpuU5Gs9pSngPnDvFE" "2BILvwRFCGq30Ehnhm8USZ1zc5m2nw6S97LFPNFepnB6h+575OHfHX6Eaothpcz" "BK+91UMVId13iTu9d1HaGgHriK6BcasSuN0iTfvbvnGc4=") kwnSig1p0 = ( # openssl 1.0.1e or 1.0.0-fips "eWv7oIGw9hnWgSmicFxakPOsxGMeEh8Dxf/HlqP0aSX+qJ8+whMeJ3Ol7AgjsrN" "mfk//J4mywjLeBp5ny5BBd15mDeaOLn1ETmkiXePhomQiGAaynfyQfEOw/F6/Ux" "03rlYerys2Cktgpya8ezxbOwJcOCnHKydnf1xkGDdFywc=") return (_abspath(pub), _abspath(priv), _abspath(pphr), bits, (kwnSig0p9p8, kwnSig1p0))
def _known_values_no_pphr(folder='.'): bits = '1024' pub = os.path.join(folder, 'pubKnown_no_pphr') pubkey = """-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3jHEfUzcy4B8N/Neiee3XYGiy SNsNU9jB/tUwEOS3gSOs4IQGGkL7bwvqfby+UwFTHx3F2UfIANQ5qtq6xY88JaV7 kgpx84K96CneT9x8zSr71ZPmKeQJWDLq0V15jo3ABUj8gvPMiytWA0IhhiaCrZrI bCjd/2UTJlSVnAxuBwIDAQAB -----END PUBLIC KEY----- """.replace(' ', '') if not isfile(pub): with open(pub, write_mode) as fd: fd.write(pubkey) priv = os.path.join(folder, 'privKnown_no_pphr') privkey = """-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQC3jHEfUzcy4B8N/Neiee3XYGiySNsNU9jB/tUwEOS3gSOs4IQG GkL7bwvqfby+UwFTHx3F2UfIANQ5qtq6xY88JaV7kgpx84K96CneT9x8zSr71ZPm KeQJWDLq0V15jo3ABUj8gvPMiytWA0IhhiaCrZrIbCjd/2UTJlSVnAxuBwIDAQAB AoGAOq1cEI6Sy+HYK6mT6e4eucapUa120bjnR4VG8/nClGNlW0PfEPBeT3D9lzYh G5r/hmohI3nFt8uEDPdwu1qi4iWp+WRUBJKYhw31g5xLMuKoQ7ICYc4iJSggigZc 5EGPA/QyfIBxzNSK6wSAi1H1Y9iF6FK4912RwnNl/1eTM4ECQQDnDl+dZA/tGSHi mJ9ZGDviq7GDmGls3SBS0GGCNC3Woj3DfZv8PL2eTs4l9JMR7F+6/DwxMlikqzgE wP/I2g7HAkEAy10eATfgJ3azRL6rT+HMAamf8pNY222uO27mbmsi5snmfJx7+I5B eJOQdiS15ymVCZgS1tZJQT91SLI70BxmwQJAfCywXDDLklvgZxwo/0PT41TsmNGP Tw9j8L3Guaf7Po+A7BAUhbHLIkot5h4T8Bz9scsfOj1ZgF34RC3JCZOPPwJAExY3 Rbf/0tRiOPaIT6QKqLFJ8NOBiH6/1pYvDHgDu5OBjXqGbCq13GJFMcF6TSrq8Q6T 3hQYpgYVtO/9iyfPQQJAJbZ3Xw7q8i0vNp/3XsG2S90j9lZ9c6OKwdtRavjWWVm5 kIZMrRBdjmx7EWpoJ52OVCO+21FtLzUz+I3O4yJDtg== -----END RSA PRIVATE KEY----- """.replace(' ', '') if not isfile(priv): with open(priv, write_mode) as fd: fd.write(privkey) kwnSig0p9p8 = ( # openssl 0.9.8r "") kwnSig1p0 = ( # openssl 1.0.1e or 1.0.0-fips "") return (_abspath(pub), _abspath(priv), bits, (kwnSig0p9p8, kwnSig1p0))
def test_dropbox_stuff(self): # assume that is_in_dropbox returns actual Dropbox folder, or False # test whether decrypt() will refuse to proceed inside it # use real Dropbox path if this test machine has it, otherwise fake it real_dropbox_path = get_dropbox_path() # sets dropbox_path global #global dropbox_path orig_path = pyfilesec.dropbox_path # set up a path and a file if real_dropbox_path == False: fake_dropbox_path = _abspath('.') pyfilesec.dropbox_path = fake_dropbox_path # set global var assert get_dropbox_path() == fake_dropbox_path test_path = os.path.join(pyfilesec.dropbox_path, 'test.txt') with open(test_path, 'wb') as fd: fd.write('test db file contents') assert isfile(test_path) # raise FileStatusError if try to decrypt in Dropbox folder pub, priv, pphr = _known_values()[:3] sf = SecFile(test_path) sf.encrypt(pub, keep=True) assert sf.is_in_dropbox # whether real or fake with pytest.raises(FileStatusError): sf.decrypt(priv, pphr) os.unlink(test_path) #os.unlink(sf.file) sf.destroy() # get coverage # partial test of get_dropbox_path() pyfilesec.dropbox_path = None if real_dropbox_path and sys.platform != 'win32': host_db = os.path.expanduser('~/.dropbox/host.db') # temporarily moves your actual dropbox locator file # seems safe enough: gets auto-rebuilt by Dropbox if file is lost if exists(host_db): try: os.rename(host_db, host_db + '.orig') get_dropbox_path() assert sf.is_in_dropbox == False # bc no dropbox now finally: os.rename(host_db + '.orig', host_db) assert pyfilesec.dropbox_path == False pyfilesec.dropbox_path = orig_path
def test_command_line(self): """test command line usage with lib_path == path to invoke pyfilesec""" # minimal test of args via commandline: recover --version via stderr cmdLineCmd = [sys.executable, lib_path, '--version'] _, ver = sys_call(cmdLineCmd, stderr=True) # can be coverage warnings in stderr as well, so take first line: assert ver.splitlines()[0] == pyfilesec.__version__ # send encrypt and decrypt commands via command line datafile = 'cleartext no unicode.txt' secretText = 'secret snippet %.6f' % get_time() with open(datafile, write_mode) as fd: fd.write(secretText) pub1, priv1, pphr1 = _known_values()[:3] datafile = _abspath(datafile) hmac = 'hmac' with open(hmac, write_mode) as fd: fd.write('hmac here') # Encrypt: cmdLineCmd = [ sys.executable, lib_path, datafile, '--encrypt', '--pub', pub1, '--keep', '--openssl=' + OPENSSL ] oute = sys_call(cmdLineCmd) assert 'cipher_text' in oute enc = eval(oute) assert isfile(enc['cipher_text']) # Decrypt: cmdLineCmd = [ sys.executable, lib_path, enc['cipher_text'], '--decrypt', '--keep', '--nocheck', '--priv', priv1, '--pphr', pphr1, '--openssl=' + OPENSSL ] outd = sys_call(cmdLineCmd) assert 'clear_text' in outd dec = eval(outd) assert isfile(dec['clear_text']) recoveredText = open(dec['clear_text']).read() assert recoveredText == secretText # need both enc and dec to work # Rotate: ciph = enc['cipher_text'] assert (isfile(ciph) and ciph.endswith(ENC_EXT)) # need --keep in d cmdLineRotate = [ sys.executable, lib_path, '--nocheck', enc['cipher_text'], '--rotate', '--hmac', hmac, '--pub', pub1, '--priv', priv1, '--pphr', pphr1, '-z', str(getsize(ciph) * 2) ] outr = sys_call(cmdLineRotate) # dict as a string assert 'rotate' in outr and 'good' in outr assert 'hmac' in outr rot = eval(outr) assert isfile(rot['file']) # Sign and Verify (target = the file from rot): cmdLineSign = [ sys.executable, lib_path, rot['file'], '--sign', '--priv', priv1, '--pphr', pphr1, '--out', 'sig.out' ] outs = sys_call(cmdLineSign) assert 'sig' in outs sig = eval(outs) cmdLineVerify = [ sys.executable, lib_path, rot['file'], '--verify', '--pub', pub1, '--sig', sig['out'], '--nocheck' ] outv = sys_call(cmdLineVerify) assert 'verified' in outv out = eval(outv) assert out['verified'] # need both sign and verify to work # Pad, unpad: with open(datafile, write_mode) as fd: fd.write(secretText) orig_size = getsize(datafile) cmdLinePad = [sys.executable, lib_path, datafile, '--nocheck', '--pad'] outp = sys_call(cmdLinePad) assert "'method': 'pad'" in outp assert "'size': %d" % DEFAULT_PAD_SIZE in outp out = eval(outp) assert getsize(datafile) == DEFAULT_PAD_SIZE # more coverage cmdLineUnpad = [ sys.executable, lib_path, datafile, '--nocheck', '--pad', '-z', '0' ] outunp = sys_call(cmdLineUnpad) assert 'padding' in outunp out = eval(outunp) assert out['padding'] == None cmdLineUnpad = [ sys.executable, lib_path, datafile, '--pad', '-z', '0', '--verbose' ] outv = sys_call(cmdLineUnpad) # see if there's lots of output, with some plausible detail: assert outv.startswith('0.0') assert lib_name in outv assert len(outv) > 800 assert len(outv.splitlines()) > 40 # no actual action: cmdLineCmd = [sys.executable, lib_path, '--nocheck', datafile] out = sys_call(cmdLineCmd) assert 'None' in out # Destroy: cmdLineDestroy = [sys.executable, lib_path, datafile, '--destroy'] outx = sys_call(cmdLineDestroy) if 'disposition' in outx: out = eval(outx) assert out['disposition'] == destroy_code[pfs_DESTROYED] # file specified but missing on file system cmdLineCmd = [sys.executable, lib_path, '--nocheck', datafile] out = sys_call(cmdLineCmd) assert out.startswith('no such file')