jdennis%redhat.com caf62c0df9 commit for release 0.12, see doc/Changelog for details.
Major enhancement is PKCS12 support.


git-svn-id: svn://10.0.0.236/trunk@262367 18797224-902f-48f8-a5cc-f745e15eee43
2011-06-06 15:21:13 +00:00

171 lines
6.1 KiB
Python
Executable File

#!/usr/bin/python
import sys
import os
import unittest
import nss.nss as nss
#-------------------------------------------------------------------------------
verbose = False
mechanism = nss.CKM_DES_CBC_PAD
plain_text = "Encrypt me!"
key = "e8:a7:7c:e2:05:63:6a:31"
iv = "e4:bb:3b:d3:c3:71:2e:58"
in_filename = sys.argv[0]
chunk_size = 128
#-------------------------------------------------------------------------------
def setup_contexts(mechanism, key, iv):
# Get a PK11 slot based on the cipher
slot = nss.get_best_slot(mechanism)
# If key was supplied use it, otherwise generate one
if key:
if verbose:
print "using supplied key data"
print "key:\n%s" % (key)
key_si = nss.SecItem(nss.read_hex(key))
sym_key = nss.import_sym_key(slot, mechanism, nss.PK11_OriginUnwrap,
nss.CKA_ENCRYPT, key_si)
else:
if verbose:
print "generating key data"
sym_key = slot.key_gen(mechanism, None, slot.get_best_key_length(mechanism))
# If initialization vector was supplied use it, otherwise set it to None
if iv:
if verbose:
print "supplied iv:\n%s" % (iv)
iv_data = nss.read_hex(iv)
iv_si = nss.SecItem(iv_data)
iv_param = nss.param_from_iv(mechanism, iv_si)
else:
iv_length = nss.get_iv_length(mechanism)
if iv_length > 0:
iv_data = nss.generate_random(iv_length)
iv_si = nss.SecItem(iv_data)
iv_param = nss.param_from_iv(mechanism, iv_si)
if verbose:
print "generated %d byte initialization vector: %s" % \
(iv_length, nss.data_to_hex(iv_data, separator=":"))
else:
iv_param = None
# Create an encoding context
encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
sym_key, iv_param)
# Create a decoding context
decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
sym_key, iv_param)
return encoding_ctx, decoding_ctx
#-------------------------------------------------------------------------------
class TestCipher(unittest.TestCase):
def setUp(self):
nss.nss_init_nodb()
self.encoding_ctx, self.decoding_ctx = setup_contexts(mechanism, key, iv)
def tearDown(self):
del self.encoding_ctx
del self.decoding_ctx
nss.nss_shutdown()
def test_string(self):
if verbose:
print "Plain Text:\n%s" % (plain_text)
# Encode the plain text by feeding it to cipher_op getting cipher text back.
# Append the final bit of cipher text by calling digest_final
cipher_text = self.encoding_ctx.cipher_op(plain_text)
cipher_text += self.encoding_ctx.digest_final()
if verbose:
print "Cipher Text:\n%s" % (nss.data_to_hex(cipher_text, separator=":"))
# Decode the cipher text by feeding it to cipher_op getting plain text back.
# Append the final bit of plain text by calling digest_final
decoded_text = self.decoding_ctx.cipher_op(cipher_text)
decoded_text += self.decoding_ctx.digest_final()
if verbose:
print "Decoded Text:\n%s" % (decoded_text)
# Validate the encryption/decryption by comparing the decoded text with
# the original plain text, they should match.
self.assertEqual(decoded_text, plain_text)
self.assertNotEqual(cipher_text, plain_text)
def test_file(self):
encrypted_filename = os.path.basename(in_filename) + ".encrypted"
decrypted_filename = os.path.basename(in_filename) + ".decrypted"
in_file = open(in_filename, "r")
encrypted_file = open(encrypted_filename, "w")
if verbose:
print "Encrypting file \"%s\" to \"%s\"" % (in_filename, encrypted_filename)
# Encode the data read from a file in chunks
while True:
# Read a chunk of data until EOF, encrypt it and write the encrypted data
in_data = in_file.read(chunk_size)
if len(in_data) == 0: # EOF
break
encrypted_data = self.encoding_ctx.cipher_op(in_data)
encrypted_file.write(encrypted_data)
# Done encoding the input, get the final encoded data, write it, close files
encrypted_data = self.encoding_ctx.digest_final()
encrypted_file.write(encrypted_data)
in_file.close()
encrypted_file.close()
# Decode the encoded file in a similar fashion
if verbose:
print "Decrypting file \"%s\" to \"%s\"" % (encrypted_filename, decrypted_filename)
encrypted_file = open(encrypted_filename, "r")
decrypted_file = open(decrypted_filename, "w")
while True:
# Read a chunk of data until EOF, encrypt it and write the encrypted data
in_data = encrypted_file.read(chunk_size)
if len(in_data) == 0: # EOF
break
decrypted_data = self.decoding_ctx.cipher_op(in_data)
decrypted_file.write(decrypted_data)
# Done encoding the input, get the final encoded data, write it, close files
decrypted_data = self.decoding_ctx.digest_final()
decrypted_file.write(decrypted_data)
encrypted_file.close()
decrypted_file.close()
# Validate the encryption/decryption by comparing the decoded text with
# the original plain text, they should match.
in_data = open(in_filename).read()
encrypted_data = open(encrypted_filename).read()
decrypted_data = open(decrypted_filename).read()
if decrypted_data != in_data:
result = 1
print "FAILED! decrypted_data != in_data"
if encrypted_data == in_data:
result = 1
print "FAILED! encrypted_data == in_data"
# clean up
os.unlink(encrypted_filename)
os.unlink(decrypted_filename)
#-------------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()