def rnpkey_generate_multiple(): # Generate 5 keys with different user ids for i in range(0, 5): # generate the next key pipe = pswd_pipe(PASSWORD) userid = str(i) + '@rnp-multiple' ret, out, err = run_proc(RNPK, [ '--numbits', '2048', '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', userid, '--generate-key' ]) os.close(pipe) if ret != 0: raise_err('key generation failed', err) # list keys using the rnpkeys, checking whether it reports correct key number ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys']) if ret != 0: raise_err('key list failed', err) match = re.match(RE_MULTIPLE_KEY_LIST, out) if not match: raise_err('wrong key list output', out) if not match.group(1) == str((i + 1) * 2): raise_err('wrong key count', out) # Checking the 5 keys output ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys']) if ret != 0: raise_err('key list failed', err) match = re.match(RE_MULTIPLE_KEY_5, out) if not match: raise_err('wrong key list output', out) # Cleanup and return clear_keyrings() return
def setup(workdir): # Searching for rnp and gnupg global RNP, GPG, RNPK, WORKDIR, RNPDIR, GPGDIR, SMALLSIZE, RMWORKDIR logging.basicConfig(stream=sys.stdout, format="%(message)s") logging.getLogger().setLevel(logging.INFO) RNP = rnp_file_path('src/rnp/rnp') RNPK = rnp_file_path('src/rnpkeys/rnpkeys') GPG = find_utility('gpg') WORKDIR = os.getcwd() if workdir: WORKDIR = workdir elif not '/tmp/' in WORKDIR: WORKDIR = tempfile.mkdtemp(prefix='rnpptmp') RMWORKDIR = True logging.debug('Setting up test in {} ...'.format(WORKDIR)) # Creating working directory and populating it with test files RNPDIR = path.join(WORKDIR, '.rnp') GPGDIR = path.join(WORKDIR, '.gpg') os.mkdir(RNPDIR, 0700) os.mkdir(GPGDIR, 0700) # Generating key pipe = pswd_pipe(PASSWORD) params = [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'performance@rnp', '--generate-key' ] # Run key generation ret, out, err = run_proc(RNPK, params) os.close(pipe) # Importing keys to GnuPG so it can build trustdb and so on ret, out, err = run_proc(GPG, [ '--batch', '--passphrase', '', '--homedir', GPGDIR, '--import', path.join(RNPDIR, 'pubring.gpg'), path.join(RNPDIR, 'secring.gpg') ]) # Generating small file for tests SMALLSIZE = 3312 st = 'lorem ipsum dol ' * (SMALLSIZE / 16) with open(path.join(WORKDIR, SMALLFILE), 'w+') as small_file: small_file.write(st) # Generating large file for tests print 'Generating large file of size {}'.format( size_to_readable(LARGESIZE)) st = '0123456789ABCDEF' * (1024 / 16) with open(path.join(WORKDIR, LARGEFILE), 'w') as fd: for i in range(0, LARGESIZE / 1024 - 1): fd.write(st)
def rnpkey_generate_rsa(bits=None, cleanup=True): # Setup command line params if bits: params = ['--numbits', str(bits)] else: params = [] bits = 2048 userid = str(bits) + '@rnptest' # Open pipe for password pipe = pswd_pipe(PASSWORD) params = params + [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', userid, '--generate-key' ] # Run key generation ret, out, err = run_proc(RNPK, params) os.close(pipe) if ret != 0: raise_err('key generation failed', err) # Check packets using the gpg match = check_packets(path.join(RNPDIR, 'pubring.gpg'), RE_RSA_KEY) if not match: raise_err('generated key check failed') keybits = int(match.group(1)) if keybits > bits or keybits <= bits - 8: raise_err('wrong key bits') keyid = match.group(2) if not match.group(3) == userid: raise_err('wrong user id') # List keys using the rnpkeys ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys']) if ret != 0: raise_err('key list failed', err) match = re.match(RE_RSA_KEY_LIST, out) # Compare key ids if not match: raise_err('wrong key list output', out) if not match.group(3)[-16:] == match.group(2) or not match.group( 2) == keyid.lower(): raise_err('wrong key ids') if not match.group(1) == str(bits): raise_err('wrong key bits in list') # Import key to the gnupg ret, out, err = run_proc(GPG, [ '--batch', '--passphrase', PASSWORD, '--homedir', GPGDIR, '--import', path.join(RNPDIR, 'pubring.gpg'), path.join(RNPDIR, 'secring.gpg') ]) if ret != 0: raise_err('gpg key import failed', err) # Cleanup and return if cleanup: clear_keyrings() return None else: return keyid
def gpg_import_pubring(kpath=None): if not kpath: kpath = path.join(RNPDIR, 'pubring.gpg') ret, out, err = run_proc( GPG, ['--batch', '--homedir', GPGDIR, '--import', kpath]) if ret != 0: raise_err('gpg key import failed', err)
def gpg_decrypt_file(src, dst, keypass): ret, out, err = run_proc(GPG, [ '--homedir', GPGDIR, '--pinentry-mode=loopback', '--batch', '--yes', '--passphrase', keypass, '--trust-model', 'always', '-o', dst, '-d', src ]) if ret != 0: raise_err('gpg decryption failed', err)
def rnp_sign_cleartext(src, dst, signer): pipe = pswd_pipe(PASSWORD) ret, out, err = run_proc(RNP, [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', signer, '--output', dst, '--clearsign', src ]) os.close(pipe) if ret != 0: raise_err('rnp cleartext signing failed', err)
def gpg_import_secring(kpath=None): if not kpath: kpath = path.join(RNPDIR, 'secring.gpg') ret, out, err = run_proc(GPG, [ '--batch', '--passphrase', PASSWORD, '--homedir', GPGDIR, '--import', kpath ]) if ret != 0: raise_err('gpg secret key import failed', err)
def rnp_decrypt_file(src, dst): pipe = pswd_pipe(PASSWORD) ret, out, err = run_proc(RNP, [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--decrypt', src, '--output', dst ]) os.close(pipe) if ret != 0: raise_err('rnp decryption failed', out + err)
def gpg_sign_cleartext(src, dst, signer): params = [ '--homedir', GPGDIR, '--pinentry-mode=loopback', '--batch', '--yes', '--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '-o', dst, '--clearsign', src ] ret, out, err = run_proc(GPG, params) if ret != 0: raise_err('gpg cleartext signing failed', err)
def check_packets(fname, regexp): ret, output, err = run_proc(GPG, ['--list-packets', fname]) if ret != 0: print err return None else: result = re.match(regexp, output) if not result and DEBUG: print 'Wrong packets: \n' + output return result
def rnp_encrypt_file(recipient, src, dst, zlevel=6, zalgo='zip', armour=False): params = [ '--homedir', RNPDIR, '--userid', recipient, '-z', str(zlevel), '--' + zalgo, '--encrypt', src, '--output', dst ] if armour: params += ['--armor'] ret, out, err = run_proc(RNP, params) if ret != 0: raise_err('rnp encryption failed', err)
def rnp_genkey_rsa(userid, bits=2048): pipe = pswd_pipe(PASSWORD) ret, out, err = run_proc(RNPK, [ '--numbits', str(bits), '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', userid, '--generate-key' ]) os.close(pipe) if ret != 0: raise_err('rsa key generation failed', err)
def rnp_verify_detached(sig, signer=None): ret, out, err = run_proc(RNP, ['--homedir', RNPDIR, '--verify', sig]) if ret != 0: raise_err('rnp detached verification failed', err + out) # Check RNP output match = re.match(RE_RNP_GOOD_SIGNATURE, err) if not match: raise_err('wrong rnp detached verification output', err) if signer and (not match.group(1).strip() == signer.strip()): raise_err('rnp detached verification failed, wrong signer')
def rnp_verify_cleartext(src, signer=None): params = ['--homedir', RNPDIR, '--verify', src] ret, out, err = run_proc(RNP, params) if ret != 0: raise_err('rnp verification failed', err + out) # Check RNP output match = re.match(RE_RNP_GOOD_SIGNATURE, err) if not match: raise_err('wrong rnp verification output', err) if signer and (not match.group(1).strip() == signer.strip()): raise_err('rnp verification failed, wrong signer')
def gpg_sign_detached(src, signer, armour=False): params = [ '--homedir', GPGDIR, '--pinentry-mode=loopback', '--batch', '--yes', '--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '--detach-sign', src ] if armour: params.insert(2, '--armor') ret, out, err = run_proc(GPG, params) if ret != 0: raise_err('gpg detached signing failed', err)
def gpg_sign_file(src, dst, signer, zlevel=6, zalgo=1, armour=False): params = [ '--homedir', GPGDIR, '--pinentry-mode=loopback', '-z', str(zlevel), '--compress-algo', str(zalgo), '--batch', '--yes', '--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '-o', dst, '-s', src ] if armour: params.insert(2, '--armor') ret, out, err = run_proc(GPG, params) if ret != 0: raise_err('gpg signing failed', err)
def gpg_encrypt_file(src, dst, cipher='AES', zlevel=6, zalgo=1, armour=False): params = [ '--homedir', GPGDIR, '-e', '-z', str(zlevel), '--compress-algo', str(zalgo), '-r', KEY_ENCRYPT, '--batch', '--cipher-algo', cipher, '--trust-model', 'always', '--output', dst, src ] if armour: params.insert(2, '--armor') ret, out, err = run_proc(GPG, params) if ret != 0: raise_err('gpg encryption failed for cipher ' + cipher, err)
def rnp_sign_detached(src, signer, armour=False): pipe = pswd_pipe(PASSWORD) params = [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', signer, '--sign', '--detach', src ] if armour: params += ['--armor'] ret, out, err = run_proc(RNP, params) os.close(pipe) if ret != 0: raise_err('rnp detached signing failed', err)
def gpg_verify_cleartext(src, signer=None): ret, out, err = run_proc(GPG, [ '--homedir', GPGDIR, '--batch', '--yes', '--trust-model', 'always', '--verify', src ]) if ret != 0: raise_err('gpg cleartext verification failed', err) # Check GPG output match = re.match(RE_GPG_GOOD_SIGNATURE, err) if not match: raise_err('wrong gpg verification output', err) if signer and (not match.group(1) == signer): raise_err('gpg verification failed, wrong signer')
def rnpkey_export_to_gpg(cleanup=True): # Open pipe for password pipe = pswd_pipe(PASSWORD) # Run key generation ret, out, err = run_proc(RNPK, [ '--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'rsakey@rnp', '--generate-key' ]) os.close(pipe) if ret != 0: raise_err('key generation failed', err) # Export key ret, out, err = run_proc( RNPK, ['--homedir', RNPDIR, '--export-key', 'rsakey@rnp']) if ret != 0: raise_err('key export failed', err) pubpath = path.join(RNPDIR, 'rnpkey-pub.asc') with open(pubpath, 'w+') as f: f.write(out) # Import key with GPG ret, out, err = run_proc( GPG, ['--batch', '--homedir', GPGDIR, '--import', pubpath]) if ret != 0: raise_err('gpg : public key import failed', err) if cleanup: clear_keyrings()
def rnpkey_import_from_gpg(cleanup=True): # Generate key in GnuPG ret, out, err = run_proc(GPG, [ '--batch', '--homedir', GPGDIR, '--passphrase', '', '--quick-generate-key', 'rsakey@gpg', 'rsa' ]) if ret != 0: raise_err('gpg key generation failed', err) # Getting fingerprint of the generated key ret, out, err = run_proc(GPG, ['--batch', '--homedir', GPGDIR, '--list-keys']) match = re.match(RE_GPG_SINGLE_RSA_KEY, out) if not match: raise_err('wrong gpg key list output', out) keyfp = match.group(1) # Exporting generated public key ret, out, err = run_proc( GPG, ['--batch', '--homedir', GPGDIR, '--armour', '--export', keyfp]) if ret != 0: raise_err('gpg : public key export failed', err) pubpath = path.join(RNPDIR, keyfp + '-pub.asc') with open(pubpath, 'w+') as f: f.write(out) # Exporting generated secret key ret, out, err = run_proc(GPG, [ '--batch', '--homedir', GPGDIR, '--armour', '--export-secret-key', keyfp ]) if ret != 0: raise_err('gpg : secret key export failed', err) secpath = path.join(RNPDIR, keyfp + '-sec.asc') with open(secpath, 'w+') as f: f.write(out) # Importing public key to rnp ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--import-key', pubpath]) if ret != 0: raise_err('rnp : public key import failed', err) # Importing secret key to rnp ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--import-key', secpath]) if ret != 0: raise_err('rnp : secret key import failed', err) # We do not check keyrings after the import - imported by RNP keys are not saved yet if cleanup: clear_keyrings()