[Python-modules-commits] [pykcs11] 01/03: New upstream version 1.4.4
Ludovic Rousseau
rousseau at moszumanska.debian.org
Wed Oct 11 13:56:53 UTC 2017
This is an automated email from the git hooks/post-receive script.
rousseau pushed a commit to branch master
in repository pykcs11.
commit ec1a373715c53a9e3e0be65c08fa55a5171063d0
Author: Ludovic Rousseau <rousseau at debian.org>
Date: Wed Oct 11 14:41:21 2017 +0200
New upstream version 1.4.4
---
MANIFEST | 12 +++
Makefile | 1 +
PKG-INFO | 2 +-
PyKCS11/__init__.py | 46 +++++++---
README.md | 11 +++
run_test.py | 38 ++++++++
samples/dumpit.py | 10 ++-
samples/encrypt.py | 6 +-
samples/generate.py | 2 +-
samples/genkeypair_import_cert.py | 2 +
samples/getinfo.py | 10 ++-
samples/modulus.py | 4 +-
samples/{generate.py => rsa_encrypt.py} | 18 ++--
samples/signature.py | 6 +-
samples/unblock.py | 2 +-
setup.py | 4 +-
src/opensc/pkcs11.h | 2 +-
tests/__init__.py | 0
tests/test_CK.py | 23 +++++
tests/test_asymetric.py | 154 ++++++++++++++++++++++++++++++++
tests/test_ckbytelist.py | 84 +++++++++++++++++
tests/test_digest.py | 38 ++++++++
tests/test_exception.py | 42 +++++++++
tests/test_info.py | 43 +++++++++
tests/test_random.py | 27 ++++++
tests/test_symetric.py | 97 ++++++++++++++++++++
tox.ini | 16 ++++
27 files changed, 661 insertions(+), 39 deletions(-)
diff --git a/MANIFEST b/MANIFEST
index 254e192..7a38e8b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -14,6 +14,7 @@ samples/generate.py
samples/genkeypair_import_cert.py
samples/getinfo.py
samples/modulus.py
+samples/rsa_encrypt.py
samples/signature.py
samples/unblock.py
samples/LowLevel/dumpit.py
@@ -23,6 +24,7 @@ samples/LowLevel/test.py
samples/LowLevel/test1.py
PyKCS11/LowLevel.py
PyKCS11/__init__.py
+run_test.py
src/ck_attribute_smart.cpp
src/ck_attribute_smart.h
src/dyn_generic.h
@@ -41,3 +43,13 @@ src/utility.cpp
src/utility.h
src/opensc/pkcs11.h
src/pykcs11_wrap.cpp
+tests/__init__.py
+tests/test_CK.py
+tests/test_asymetric.py
+tests/test_ckbytelist.py
+tests/test_digest.py
+tests/test_exception.py
+tests/test_info.py
+tests/test_random.py
+tests/test_symetric.py
+tox.ini
diff --git a/Makefile b/Makefile
index 1bb07bb..50f5f20 100644
--- a/Makefile
+++ b/Makefile
@@ -54,6 +54,7 @@ doc: build
epydoc --verbose PyKCS11
doc-upload: doc
+ rm -r api
mv html api
scp -r api ludov at web.sourceforge.net:/home/project-web/pkcs11wrap/htdocs
diff --git a/PKG-INFO b/PKG-INFO
index 8b383cc..2acc375 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: PyKCS11
-Version: 1.4.3
+Version: 1.4.4
Summary: A Full PKCS#11 wrapper for Python
Home-page: https://github.com/LudovicRousseau/PyKCS11
Author: Ludovic Rousseau
diff --git a/PyKCS11/__init__.py b/PyKCS11/__init__.py
index a2eda95..eae812b 100644
--- a/PyKCS11/__init__.py
+++ b/PyKCS11/__init__.py
@@ -116,7 +116,7 @@ class ckbytelist(PyKCS11.LowLevel.ckbytelist):
return the representation of a tuple
the __str__ method will use it also
"""
- rep = [elt for elt in self]
+ rep = [int(elt) for elt in self]
return repr(rep)
@@ -441,10 +441,15 @@ class PyKCS11Error(Exception):
The text representation of a PKCS#11 error is something like:
"CKR_DEVICE_ERROR (0x00000030)"
"""
- if (self.value < 0):
- return CKR[self.value] + " (%s)" % self.text
+ if self.value in CKR:
+ if self.value < 0:
+ return CKR[self.value] + " (%s)" % self.text
+ else:
+ return CKR[self.value] + " (0x%08X)" % self.value
+ elif self.value & CKR_VENDOR_DEFINED:
+ return "Vendor error (0x%08X)" % (self.value & 0xffffffff & ~CKR_VENDOR_DEFINED)
else:
- return CKR[self.value] + " (0x%08X)" % self.value
+ return "Unknown error (0x%08X)" % self.value
class PyKCS11Lib(object):
@@ -962,7 +967,7 @@ class Session(object):
@param mecha: the digesting mechanism to be used
@type mecha: L{Mechanism} instance or L{MechanismSHA1}
for CKM_SHA_1
- @return: A DigestSession object
+ @return: A L{DigestSession} object
@rtype: DigestSession
"""
return DigestSession(self.lib, self.session, mecha)
@@ -981,6 +986,8 @@ class Session(object):
@note: the returned value is an istance of L{ckbytelist}.
You can easly convert it to a binary string with::
+ bytes(ckbytelistDigest)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistDigest)
"""
@@ -1016,6 +1023,8 @@ class Session(object):
@note: the returned value is an instance of L{ckbytelist}.
You can easly convert it to a binary string with::
+ bytes(ckbytelistSignature)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistSignature)
"""
@@ -1081,6 +1090,8 @@ class Session(object):
@note: the returned value is an instance of L{ckbytelist}.
You can easly convert it to a binary string with::
+ bytes(ckbytelistEncrypted)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistEncrypted)
"""
@@ -1116,6 +1127,8 @@ class Session(object):
@note: the returned value is an instance of L{ckbytelist}.
You can easly convert it to a binary string with::
+ bytes(ckbytelistData)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistData)
"""
@@ -1151,6 +1164,8 @@ class Session(object):
@note: the returned value is an instance of L{ckbytelist}.
You can easily convert it to a binary string with::
+ bytes(ckbytelistData)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistData)
"""
@@ -1377,9 +1392,12 @@ class Session(object):
@note: if allAsBinary is True the function do not convert results to
Python types (i.e.: CKA_TOKEN to Bool, CKA_CLASS to int, ...).
+
Binary data is returned as L{ckbytelist} type, usable
as a list containing only bytes.
You can easly convert it to a binary string with::
+ bytes(ckbytelistVariable)
+ or, for Python 2::
''.join(chr(i) for i in ckbytelistVariable)
"""
@@ -1388,8 +1406,8 @@ class Session(object):
valTemplate[x].SetType(attr[x])
# first call to get the attribute size and reserve the memory
rv = self.lib.C_GetAttributeValue(self.session, obj_id, valTemplate)
- if rv == CKR_ATTRIBUTE_TYPE_INVALID \
- or rv == CKR_ATTRIBUTE_SENSITIVE:
+ if rv in (CKR_ATTRIBUTE_TYPE_INVALID, CKR_ATTRIBUTE_SENSITIVE,
+ CKR_ARGUMENTS_BAD):
return self.getAttributeValue_fragmented(obj_id, attr, allAsBinary)
if rv != CKR_OK:
@@ -1401,7 +1419,7 @@ class Session(object):
res = []
for x in range(len(attr)):
- if (allAsBinary):
+ if allAsBinary:
res.append(valTemplate[x].GetBin())
elif valTemplate[x].IsNum():
res.append(valTemplate[x].GetNum())
@@ -1434,8 +1452,8 @@ class Session(object):
valTemplate[0].SetType(attr[x])
# first call to get the attribute size and reserve the memory
rv = self.lib.C_GetAttributeValue(self.session, obj_id, valTemplate)
- if rv == CKR_ATTRIBUTE_TYPE_INVALID \
- or rv == CKR_ATTRIBUTE_SENSITIVE:
+ if rv in (CKR_ATTRIBUTE_TYPE_INVALID,
+ CKR_ATTRIBUTE_SENSITIVE, CKR_ARGUMENTS_BAD):
# append an empty value
res.append(None)
continue
@@ -1447,7 +1465,7 @@ class Session(object):
if rv != CKR_OK:
raise PyKCS11Error(rv)
- if (allAsBinary):
+ if allAsBinary:
res.append(valTemplate[0].GetBin())
elif valTemplate[0].IsNum():
res.append(valTemplate[0].GetNum())
@@ -1469,9 +1487,7 @@ class Session(object):
@param seed: seed material
@type seed: iterable
"""
- low_seed = ckbytelist(len(seed))
- for c in range(len(seed)):
- low_seed.append(seed[c])
+ low_seed = ckbytelist(seed)
rv = self.lib.C_SeedRandom(self.session, low_seed)
if rv != CKR_OK:
raise PyKCS11Error(rv)
@@ -1485,6 +1501,8 @@ class Session(object):
@note: the returned value is an instance of L{ckbytelist}.
You can easly convert it to a binary string with::
+ bytes(random)
+ or, for Python 2::
''.join(chr(i) for i in random)
"""
low_rand = ckbytelist(size)
diff --git a/README.md b/README.md
index 1aa4014..725ac73 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,17 @@ that doesn't come with the standard distribution.
History
=======
+1.4.4 - October 2017, Ludovic Rousseau
+ - getAttributeValue(): handle CKR_ARGUMENTS_BAD error
+ - seedRandom: fix the seed convertion
+ - Add vendor errors support to PyKCS11Error
+ - samples/getinfo & dumpit: list only slots with a token present by default
+ - run_test: add support of OpenSC PKCS#11 spy
+ - ckbytelist: update __repr__()
+ - include tests files in the archive
+ - dumpit: display the error if getAttributeValue() fails
+ - some minor improvements
+
1.4.3 - June 2017, Ludovic Rousseau
- Add support of CKM_RSA_PKCS_PSS mechanism
- fix CKM_AES_CBC issue with Python 3
diff --git a/run_test.py b/run_test.py
new file mode 100755
index 0000000..c4504aa
--- /dev/null
+++ b/run_test.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+# use:
+# ./run_test.py
+# ./run_test.py test_ckbytelist.py
+
+from __future__ import print_function
+
+import unittest
+import os
+import sys
+
+pattern = "test*.py"
+if len(sys.argv) > 1:
+ pattern = sys.argv[1]
+
+if "PKCS11SPY" in os.environ:
+ # use OpenSC PKCS#11 spy if PKCS11SPY is defined
+ LIBS = ["/usr/local/lib/pkcs11/pkcs11-spy.so", # macOS or local build
+ "/usr/lib/x86_64-linux-gnu/pkcs11-spy.so"] # Debian amd64
+else:
+ # use SoftHSM2 or SoftHSM1
+ LIBS = ["/usr/local/lib/softhsm/libsofthsm2.so", # macOS or local build
+ "/usr/lib/softhsm/libsofthsm2.so", # Debian libsofthsm2
+ "/usr/lib/softhsm/libsofthsm.so", # Debian libsofthsm
+ "/usr/lib/libsofthsm.so"] # Ubuntu 12.04 libsofthsm
+
+for lib in LIBS:
+ if os.path.isfile(lib):
+ print("Using lib:", lib)
+ os.environ['PYKCS11LIB'] = lib
+ break
+
+tl = unittest.TestLoader()
+suite = tl.discover("tests", pattern=pattern)
+result = unittest.TextTestRunner(verbosity=2).run(suite)
+if result.errors or result.failures:
+ sys.exit(1)
diff --git a/samples/dumpit.py b/samples/dumpit.py
index 374d7ab..8e1335c 100755
--- a/samples/dumpit.py
+++ b/samples/dumpit.py
@@ -55,6 +55,7 @@ def dump(src, length=16):
def usage():
print("Usage:", sys.argv[0], end=' ')
+ print("[-a][--all]", end=' ')
print("[-p pin][--pin=pin] (use --pin=NULL for pinpad)", end=' ')
print("[-c lib][--lib=lib]", end=' ')
print("[-S][--sign]", end=' ')
@@ -64,7 +65,8 @@ def usage():
print()
try:
- opts, args = getopt.getopt(sys.argv[1:], "p:c:Sdhs:", ["pin=", "lib=", "sign", "decrypt", "slot=", "help"])
+ opts, args = getopt.getopt(sys.argv[1:], "p:c:Sdhs:a",
+ ["pin=", "lib=", "sign", "decrypt", "slot=", "help", "all"])
except getopt.GetoptError:
# print help information and exit:
usage()
@@ -74,6 +76,7 @@ pin_available = False
decrypt = sign = False
lib = None
slot = None
+token_present = True
for o, a in opts:
if o in ("-h", "--help"):
usage()
@@ -92,6 +95,8 @@ for o, a in opts:
decrypt = True
elif o in ("-s", "--slot"):
slot = int(a)
+ if o in ("-a", "--all"):
+ token_present = False
red = blue = magenta = normal = ""
if sys.stdout.isatty() and platform.system().lower() != 'windows':
@@ -109,7 +114,7 @@ pkcs11.load(lib)
info = pkcs11.getInfo()
print("Library manufacturerID:", info.manufacturerID)
-slots = pkcs11.getSlotList()
+slots = pkcs11.getSlotList(token_present)
print("Available Slots:", len(slots), slots)
if slot is not None:
@@ -165,6 +170,7 @@ for s in slots:
try:
attributes = session.getAttributeValue(o, all_attributes)
except PyKCS11.PyKCS11Error as e:
+ print(e)
continue
attrDict = dict(list(zip(all_attributes, attributes)))
if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE_KEY \
diff --git a/samples/encrypt.py b/samples/encrypt.py
index 11240d9..316dc88 100755
--- a/samples/encrypt.py
+++ b/samples/encrypt.py
@@ -25,7 +25,7 @@ pkcs11 = PyKCS11Lib()
pkcs11.load() # define environment variable PYKCS11LIB=YourPKCS11Lib
# get 1st slot
-slot = pkcs11.getSlotList()[0]
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")
@@ -40,8 +40,8 @@ enc = session.encrypt(pubKey, binascii.unhexlify(message))
dec = session.decrypt(privKey, enc)
print("\nmessage: " + message)
-print("\nencrypted: " + binascii.hexlify(bytearray(enc)))
-print("\ndecrypted: " + bytearray(dec))
+print("\nencrypted: {}".format(binascii.hexlify(bytearray(enc))))
+print("\ndecrypted: {}".format(bytearray(dec)))
# logout
session.logout()
diff --git a/samples/generate.py b/samples/generate.py
index 3c3508c..f35ebec 100755
--- a/samples/generate.py
+++ b/samples/generate.py
@@ -22,7 +22,7 @@ pkcs11 = PyKCS11Lib()
pkcs11.load() # define environment variable PYKCS11LIB=YourPKCS11Lib
# get 1st slot
-slot = pkcs11.getSlotList()[0]
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")
diff --git a/samples/genkeypair_import_cert.py b/samples/genkeypair_import_cert.py
index eaf00ba..43d409a 100755
--- a/samples/genkeypair_import_cert.py
+++ b/samples/genkeypair_import_cert.py
@@ -111,6 +111,8 @@ cert_template = [
(PyKCS11.CKA_ID, key_id) # must be set, and DER see Table 24, X.509 Certificate Object Attributes
]
+# create the certificate object
+session.createObject(cert_template)
# logout
session.logout()
diff --git a/samples/getinfo.py b/samples/getinfo.py
index 70d17ef..0b7be92 100755
--- a/samples/getinfo.py
+++ b/samples/getinfo.py
@@ -96,6 +96,7 @@ class getInfo(object):
def usage():
print("Usage:", sys.argv[0], end=' ')
+ print("[-a][--all]", end=' ')
print("[-p pin][--pin=pin] (use 'NULL' for pinpad)", end=' ')
print("[-s slot][--slot=slot]", end=' ')
print("[-c lib][--lib=lib]", end=' ')
@@ -105,8 +106,8 @@ if __name__ == '__main__':
import getopt
try:
- opts, args = getopt.getopt(sys.argv[1:], "p:s:c:ho",
- ["pin=", "slot=", "lib=", "help", "opensession"])
+ opts, args = getopt.getopt(sys.argv[1:], "p:s:c:hoa",
+ ["pin=", "slot=", "lib=", "help", "opensession", "all"])
except getopt.GetoptError:
# print help information and exit:
usage()
@@ -115,6 +116,7 @@ if __name__ == '__main__':
slot = None
lib = None
pin = ""
+ token_present = True
for o, a in opts:
if o in ("-h", "--help"):
usage()
@@ -127,11 +129,13 @@ if __name__ == '__main__':
slot = int(a)
if o in ("-c", "--lib"):
lib = a
+ if o in ("-a", "--all"):
+ token_present = False
gi = getInfo(lib)
gi.getInfo()
- slots = gi.pkcs11.getSlotList()
+ slots = gi.pkcs11.getSlotList(token_present)
print("Available Slots:", len(slots), slots)
if len(slots) == 0:
diff --git a/samples/modulus.py b/samples/modulus.py
index 716ec90..2e9cd24 100755
--- a/samples/modulus.py
+++ b/samples/modulus.py
@@ -25,7 +25,7 @@ pkcs11 = PyKCS11Lib()
pkcs11.load() # define environment variable PYKCS11LIB=YourPKCS11Lib
# get 1st slot
-slot = pkcs11.getSlotList()[0]
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")
@@ -36,7 +36,7 @@ keyID = (0x22,)
# find public key and print modulus
pubKey = session.findObjects([(CKA_CLASS, CKO_PUBLIC_KEY), (CKA_ID, keyID)])[0]
modulus = session.getAttributeValue(pubKey, [CKA_MODULUS])[0]
-print("\nmodulus: " + binascii.hexlify(bytearray(modulus)))
+print("\nmodulus: {}".format(binascii.hexlify(bytearray(modulus))))
# logout
session.logout()
diff --git a/samples/generate.py b/samples/rsa_encrypt.py
similarity index 78%
copy from samples/generate.py
copy to samples/rsa_encrypt.py
index 3c3508c..269d945 100755
--- a/samples/generate.py
+++ b/samples/rsa_encrypt.py
@@ -22,7 +22,7 @@ pkcs11 = PyKCS11Lib()
pkcs11.load() # define environment variable PYKCS11LIB=YourPKCS11Lib
# get 1st slot
-slot = pkcs11.getSlotList()[0]
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")
@@ -31,14 +31,14 @@ pubTemplate = [
(CKA_CLASS, CKO_PUBLIC_KEY),
(CKA_TOKEN, CK_TRUE),
(CKA_PRIVATE, CK_FALSE),
- (CKA_MODULUS_BITS, 0x0400),
+ (CKA_MODULUS_BITS, 2048),
(CKA_PUBLIC_EXPONENT, (0x01, 0x00, 0x01)),
(CKA_ENCRYPT, CK_TRUE),
(CKA_VERIFY, CK_TRUE),
(CKA_VERIFY_RECOVER, CK_TRUE),
(CKA_WRAP, CK_TRUE),
- (CKA_LABEL, "My Public Key"),
- (CKA_ID, (0x22,))
+ (CKA_LABEL, "Encryption key"),
+ (CKA_ID, (0x43,))
]
privTemplate = [
@@ -49,11 +49,17 @@ privTemplate = [
(CKA_SIGN, CK_TRUE),
(CKA_SIGN_RECOVER, CK_TRUE),
(CKA_UNWRAP, CK_TRUE),
- (CKA_ID, (0x22,))
+ (CKA_ID, (0x43,))
]
(pubKey, privKey) = session.generateKeyPair(pubTemplate, privTemplate)
-# logout
+PLAINTEXT = "A test string"
+mech = RSAOAEPMechanism(CKM_SHA_1, CKG_MGF1_SHA1)
+ciphertext = session.encrypt(pubKey, PLAINTEXT, mech)
+decrypted = "".join([chr(i) for i in session.decrypt(privKey, ciphertext, mech)])
+assert decrypted == PLAINTEXT
+
session.logout()
session.closeSession()
+print("That's all folks!")
diff --git a/samples/signature.py b/samples/signature.py
index 22931cb..1d43dab 100755
--- a/samples/signature.py
+++ b/samples/signature.py
@@ -24,8 +24,8 @@ import binascii
pkcs11 = PyKCS11Lib()
pkcs11.load() # define environment variable PYKCS11LIB=YourPKCS11Lib
-# get 3rd slot
-slot = pkcs11.getSlotList()[0]
+# get 1st slot
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login("1234")
@@ -39,7 +39,7 @@ toSign = "48656c6c6f20776f726c640d0a"
# find private key and compute signature
privKey = session.findObjects([(CKA_CLASS, CKO_PRIVATE_KEY), (CKA_ID, keyID)])[0]
signature = session.sign(privKey, binascii.unhexlify(toSign), Mechanism(CKM_SHA1_RSA_PKCS, None))
-print("\nsignature: " + binascii.hexlify(bytearray(signature)))
+print("\nsignature: {}".format(binascii.hexlify(bytearray(signature))))
# find public key and verify signature
pubKey = session.findObjects([(CKA_CLASS, CKO_PUBLIC_KEY), (CKA_ID, keyID)])[0]
diff --git a/samples/unblock.py b/samples/unblock.py
index 65eeaaf..6c54ae4 100755
--- a/samples/unblock.py
+++ b/samples/unblock.py
@@ -25,7 +25,7 @@ puk = "1234"
pkcs11 = PyKCS11.PyKCS11Lib()
pkcs11.load()
-slot = pkcs11.getSlotList()[0]
+slot = pkcs11.getSlotList(tokenPresent=True)[0]
session = pkcs11.openSession(slot, PyKCS11.CKF_RW_SESSION)
session.login(puk, PyKCS11.CKU_SO)
session.initPin(pin)
diff --git a/setup.py b/setup.py
index 3ea780d..c19ba48 100755
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,7 @@ if (platform.system().lower() == 'windows'):
source_files.append("src/dyn_win32.c")
source_files.append("pykcs11.rc")
libraries_val = ["python%d%d" % pyver[:2]]
- extra_compile_args = ["/Fdvc70.pdb", "/Zi", "/GR"]
+ extra_compile_args = ["/Fdvc70.pdb", "/Zi", "/GR", "/EHsc"]
extra_link_args = ["/DEBUG", "/PDB:_LowLevel.pdb", "/SUBSYSTEM:WINDOWS", "/OPT:REF", "/OPT:ICF"]
else:
source_files.append("src/dyn_unix.c")
@@ -55,7 +55,7 @@ else:
libraries_val = []
setup(name="PyKCS11",
- version="1.4.3",
+ version="1.4.4",
description="A Full PKCS#11 wrapper for Python",
keywords="crypto,pki,pkcs11,c++",
classifiers=classifiers,
diff --git a/src/opensc/pkcs11.h b/src/opensc/pkcs11.h
index 02c7419..aabf144 100644
--- a/src/opensc/pkcs11.h
+++ b/src/opensc/pkcs11.h
@@ -707,7 +707,7 @@ struct ck_rsa_pkcs_oaep_params {
unsigned long source_data_len;
} ;
-typedef struct ck_rsa_pkcs_pss_params {
+struct ck_rsa_pkcs_pss_params {
unsigned long hashAlg;
unsigned long mgf;
unsigned long sLen;
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_CK.py b/tests/test_CK.py
new file mode 100644
index 0000000..216bc39
--- /dev/null
+++ b/tests/test_CK.py
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+
+# execute using:
+# python tests/CK_test.py
+
+import unittest
+import PyKCS11
+
+
+class TestUtil(unittest.TestCase):
+
+ def test_CKM(self):
+ self.assertEqual(PyKCS11.CKM_RSA_PKCS_KEY_PAIR_GEN, 0x00000000)
+ self.assertEqual(PyKCS11.CKM[PyKCS11.CKM_RSA_PKCS_KEY_PAIR_GEN],
+ 'CKM_RSA_PKCS_KEY_PAIR_GEN')
+
+ self.assertEqual(PyKCS11.CKM_VENDOR_DEFINED, 0x80000000)
+
+ def test_CKR(self):
+ self.assertEqual(PyKCS11.CKR_VENDOR_DEFINED, 0x80000000)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_asymetric.py b/tests/test_asymetric.py
new file mode 100644
index 0000000..c206bad
--- /dev/null
+++ b/tests/test_asymetric.py
@@ -0,0 +1,154 @@
+import unittest
+from PyKCS11 import PyKCS11
+
+
+class TestUtil(unittest.TestCase):
+
+ def setUp(self):
+ self.pkcs11 = PyKCS11.PyKCS11Lib()
+ self.pkcs11.load()
+ self.slot = self.pkcs11.getSlotList(tokenPresent=True)[0]
+ self.session = self.pkcs11.openSession(self.slot,
+ PyKCS11.CKF_SERIAL_SESSION |
+ PyKCS11.CKF_RW_SESSION)
+ self.session.login("1234")
+
+ keyID = (0x22,)
+ pubTemplate = [
+ (PyKCS11.CKA_CLASS, PyKCS11.CKO_PUBLIC_KEY),
+ (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
+ (PyKCS11.CKA_MODULUS_BITS, 0x0400),
+ (PyKCS11.CKA_PUBLIC_EXPONENT, (0x01, 0x00, 0x01)),
+ (PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_VERIFY, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_VERIFY_RECOVER, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_WRAP, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_LABEL, "My Public Key"),
+ (PyKCS11.CKA_ID, keyID)
+ ]
+
+ privTemplate = [
+ (PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY),
+ (PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_PRIVATE, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_SIGN, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_SIGN_RECOVER, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_UNWRAP, PyKCS11.CK_TRUE),
+ (PyKCS11.CKA_ID, keyID)
+ ]
+
+ (self.pubKey, self.privKey) = self.session.generateKeyPair(pubTemplate, privTemplate)
+ self.assertIsNotNone(self.pubKey)
+ self.assertIsNotNone(self.privKey)
+
+ def tearDown(self):
+ self.session.destroyObject(self.pubKey)
+ self.session.destroyObject(self.privKey)
+
+ self.session.logout()
+ self.pkcs11.closeAllSessions(self.slot)
+ del self.pkcs11
+
+ def test_sign_PKCS(self):
+ toSign = "Hello world"
+
+ # sign/verify
+ signature = self.session.sign(self.privKey, toSign,
+ PyKCS11.Mechanism(PyKCS11.CKM_SHA1_RSA_PKCS, None))
+
+ result = self.session.verify(self.pubKey, toSign, signature,
+ PyKCS11.Mechanism(PyKCS11.CKM_SHA1_RSA_PKCS, None))
+
+ self.assertTrue(result)
+
+ def test_sign_X509(self):
+ toSign = "Hello world"
+
+ # sign/verify
+ try:
+ signature = self.session.sign(self.privKey, toSign,
+ PyKCS11.Mechanism(PyKCS11.CKM_RSA_X_509, None))
+
+ result = self.session.verify(self.pubKey, toSign, signature,
+ PyKCS11.Mechanism(PyKCS11.CKM_RSA_X_509, None))
+
+ self.assertTrue(result)
+ except PyKCS11.PyKCS11Error as e:
+ # RSA X509 is not supported by SoftHSM1
+ if not e.value == PyKCS11.CKR_MECHANISM_INVALID:
+ raise
+
+ def test_encrypt_PKCS(self):
+ # encrypt/decrypt using CMK_RSA_PKCS (default)
+ dataIn = "Hello world"
+ encrypted = self.session.encrypt(self.pubKey, dataIn)
+ decrypted = self.session.decrypt(self.privKey, encrypted)
+
+ # convert in a string
+ text = "".join(map(chr, decrypted))
+
+ self.assertEqual(dataIn, text)
+
+ def test_encrypt_X509(self):
+ # encrypt/decrypt using CKM_RSA_X_509
+ dataIn = "Hello world!"
+ mecha = PyKCS11.Mechanism(PyKCS11.CKM_RSA_X_509, None)
+ try:
+ encrypted = self.session.encrypt(self.pubKey, dataIn, mecha=mecha)
+ decrypted = self.session.decrypt(self.privKey, encrypted, mecha=mecha)
+
+ # remove padding NUL bytes
+ padding_length = 0
+ for e in decrypted:
+ if e != 0:
+ break
+ padding_length += 1
+ decrypted = list(decrypted)[padding_length:]
+
+ # convert in a string
+ text = "".join(map(chr, decrypted))
+
+ self.assertEqual(dataIn, text)
+ except PyKCS11.PyKCS11Error as e:
+ # RSA X509 is not supported by SoftHSM1
+ if not e.value == PyKCS11.CKR_MECHANISM_INVALID:
+ raise
+
+ def test_RSA_OAEP(self):
+ # RSA OAEP
+ plainText = "A test string"
+
+ mech = PyKCS11.RSAOAEPMechanism(PyKCS11.CKM_SHA_1, PyKCS11.CKG_MGF1_SHA1)
+ try:
+ cipherText = self.session.encrypt(self.pubKey, plainText, mech)
+ decrypted = self.session.decrypt(self.privKey, cipherText, mech)
+
+ text = "".join(map(chr, decrypted))
+
+ self.assertEqual(text, plainText)
+ except PyKCS11.PyKCS11Error as e:
+ # RSA OAEP is not supported by SoftHSM1
+ if not e.value == PyKCS11.CKR_MECHANISM_INVALID:
+ raise
+
+ def test_RSA_PSS(self):
+ # RSA PSS
+ plainText = "A test string"
+
+ mech = PyKCS11.RSA_PSS_Mechanism(PyKCS11.CKM_SHA384, PyKCS11.CKG_MGF1_SHA384, 48)
+ try:
+ cipherText = self.session.encrypt(self.pubKey, plainText, mech)
+ decrypted = self.session.decrypt(self.privKey, cipherText, mech)
+ text = "".join(map(chr, decrypted))
+
+ self.assertEqual(text, plainText)
+ except PyKCS11.PyKCS11Error as e:
+ # RSA PSS is not yet supported by SoftHSM2
+ if not e.value == PyKCS11.CKR_MECHANISM_INVALID:
+ raise
+
+ # test CK_OBJECT_HANDLE.__repr__()
+ text = str(self.pubKey)
+ self.assertIsNotNone(text)
diff --git a/tests/test_ckbytelist.py b/tests/test_ckbytelist.py
new file mode 100644
index 0000000..82fdca8
--- /dev/null
+++ b/tests/test_ckbytelist.py
@@ -0,0 +1,84 @@
+import unittest
+import PyKCS11
+
+
+class Testutil(unittest.TestCase):
+
+ def test_empty(self):
+ ck = PyKCS11.ckbytelist()
+ self.assertSequenceEqual(ck, [])
+
+ def test_resize(self):
+ ck = PyKCS11.ckbytelist()
+ ck.resize(5)
+ self.assertSequenceEqual(ck, [0, 0, 0, 0, 0])
+
+ def test_data(self):
+ ck = PyKCS11.ckbytelist(5)
+ for index in range(5):
+ ck[index] = index
+ self.assertSequenceEqual(ck, [0, 1, 2, 3, 4])
+
+ def test_append(self):
+ ck = PyKCS11.ckbytelist()
+ for index in range(5):
+ ck.append(index)
+ self.assertSequenceEqual(ck, [0, 1, 2, 3, 4])
+
+ def test_length0(self):
+ ck = PyKCS11.ckbytelist()
+ self.assertEqual(len(ck), 0)
+
+ def test_length5(self):
+ ck = PyKCS11.ckbytelist(5)
+ self.assertEqual(len(ck), 5)
+
+ def test_string(self):
+ ck = PyKCS11.ckbytelist()
+ ck.resize(5)
+ for index in range(5):
+ ck[index] = index
+ self.assertEqual(str(ck), "[0, 1, 2, 3, 4]")
+
+ def test_init_list0(self):
+ ck = PyKCS11.ckbytelist([])
+ self.assertSequenceEqual(ck, [])
+
+ def test_init_list1(self):
+ ck = PyKCS11.ckbytelist([1])
+ self.assertSequenceEqual(ck, [1])
+
+ def test_init_list5(self):
+ ck = PyKCS11.ckbytelist([0, 1, 2, 3, 4])
+ self.assertSequenceEqual(ck, [0, 1, 2, 3, 4])
+
+ def test_init_str(self):
+ ck = PyKCS11.ckbytelist("ABC")
+ self.assertSequenceEqual(ck, [65, 66, 67])
+
+ def test_init_bytes(self):
+ ck = PyKCS11.ckbytelist(b"ABC")
+ self.assertSequenceEqual(ck, [65, 66, 67])
+
+ def test_init_ckbytelist(self):
+ ck1 = PyKCS11.ckbytelist(b"ABC")
+ ck2 = PyKCS11.ckbytelist(ck1)
+ self.assertSequenceEqual(ck2, [65, 66, 67])
+
+ def test_unknown_format(self):
+ with self.assertRaises(PyKCS11.PyKCS11Error) as cm:
+ PyKCS11.ckbytelist(dict())
+
+ the_exception = cm.exception
+ self.assertEqual(the_exception.value, -3)
+ import sys
+ if sys.version_info[0] >= 3:
+ # Python 3 and later
+ expected = "Unknown format (<class 'dict'>)"
+ else:
+ # Python 2
+ expected = "Unknown format (<type 'dict'>)"
+ self.assertEqual(str(the_exception), expected)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_digest.py b/tests/test_digest.py
new file mode 100644
index 0000000..25d1f94
--- /dev/null
+++ b/tests/test_digest.py
@@ -0,0 +1,38 @@
+#! /usr/bin/env python
+
+# execute using:
+# python tests/CK_test.py
+
+import unittest
+from PyKCS11 import PyKCS11
+
+# SHA1 of "abc"
+SHA1_abc = [0xa9, 0x99, 0x3e, 0x36, 0x47, 0x6, 0x81, 0x6a, 0xba, 0x3e,
+ 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d]
+
+
+class TestUtil(unittest.TestCase):
+
+ def setUp(self):
+ self.pkcs11 = PyKCS11.PyKCS11Lib()
+ self.pkcs11.load()
+ self.slot = self.pkcs11.getSlotList(tokenPresent=True)[0]
+ self.session = self.pkcs11.openSession(self.slot,
+ PyKCS11.CKF_SERIAL_SESSION)
+
+ def tearDown(self):
+ self.pkcs11.closeAllSessions(self.slot)
+ del self.pkcs11
+
+ def test_digest(self):
+ digest = self.session.digest("abc")
+ self.assertSequenceEqual(digest, SHA1_abc)
+
+ def test_digestSession(self):
+ digestSession = self.session.digestSession()
+ digestSession.update("abc")
+ digest = digestSession.final()
+ self.assertSequenceEqual(digest, SHA1_abc)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_exception.py b/tests/test_exception.py
new file mode 100644
index 0000000..15866e9
--- /dev/null
+++ b/tests/test_exception.py
@@ -0,0 +1,42 @@
+import unittest
+import PyKCS11
+
+
+class Testutil(unittest.TestCase):
+
+ def test_empty(self):
+ e = PyKCS11.PyKCS11Error(0)
+ self.assertEqual(e.value, 0)
+
+ def test_CKR_OK(self):
+ e = PyKCS11.PyKCS11Error(PyKCS11.CKR_OK)
+ self.assertEqual(e.value, 0)
+ self.assertEqual(str(e), "CKR_OK (0x00000000)")
+
+ def test_CKR_PIN_INVALID(self):
+ e = PyKCS11.PyKCS11Error(PyKCS11.CKR_PIN_INVALID)
+ self.assertEqual(e.value, 0xa1)
+ self.assertEqual(str(e), "CKR_PIN_INVALID (0x000000A1)")
+
+ def test_Load(self):
+ e = PyKCS11.PyKCS11Error(-1, "Pouet")
+ self.assertEqual(e.value, -1)
+ self.assertEqual(str(e), "Load (Pouet)")
+
+ def test_raise(self):
+ with self.assertRaises(PyKCS11.PyKCS11Error):
+ raise PyKCS11.PyKCS11Error(0)
+
+ def test_unknown(self):
+ e = PyKCS11.PyKCS11Error(PyKCS11.CKR_VENDOR_DEFINED - 1)
+ self.assertEqual(str(e), "Unknown error (0x7FFFFFFF)")
+
+ def test_vendor0(self):
+ e = PyKCS11.PyKCS11Error(PyKCS11.CKR_VENDOR_DEFINED, "Pouet")
+ self.assertEqual(e.value, PyKCS11.CKR_VENDOR_DEFINED)
+ self.assertEqual(str(e), "Vendor error (0x00000000)")
+
+ def test_vendor10(self):
+ e = PyKCS11.PyKCS11Error(PyKCS11.CKR_VENDOR_DEFINED + 10)
+ self.assertEqual(e.value, PyKCS11.CKR_VENDOR_DEFINED + 10)
+ self.assertEqual(str(e), "Vendor error (0x0000000A)")
diff --git a/tests/test_info.py b/tests/test_info.py
new file mode 100644
index 0000000..ff968e7
--- /dev/null
+++ b/tests/test_info.py
@@ -0,0 +1,43 @@
+import unittest
+from PyKCS11 import PyKCS11
... 199 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pykcs11.git
More information about the Python-modules-commits
mailing list