问题
A python script of mine is designed to get detailed information of slots/tokens in a particular .so library. The output looks like this:
Library manufacturerID: Safenet, Inc.
Available Slots: 4
Slot no: 0
slotDescription: ProtectServer K5E:00045
manufacturerID: SafeNet Inc.
TokenInfo
label: CKM
manufacturerID: SafeNet Inc.
model: K5E:PL25
Opened session 0x00000002
Found 38 objects: [5021, 5022, 5014, 5016, 4, 5, 6, 7, 8, 9, 16, 18, 23, 24, 26, 27, 29, 30, 32, 33, 35, 36, 38, 39, 5313, 5314, 4982, 5325, 5326, 5328, 5329, 5331, 5332, 5335, 5018, 4962, 5020, 4963]
I am able to open the session and get the information. Where I run into dubious problems is retrieving the attributes of said keys in the library.
I created my own template for desired attributes needed for my specifications, the following:
all_attributes = PyKCS11.CKA.keys()
# only use the integer values and not the strings like 'CKM_RSA_PKCS'
all_attributes = [e for e in all_attributes if isinstance(e, int)]
attributes = [
["CKA_ENCRYPT", PyKCS11.CKA_ENCRYPT],
["CKA_CLASS", PyKCS11.CKA_CLASS],
["CKA_DECRYPT", PyKCS11.CKA_DECRYPT],
["CKA_SIGN", PyKCS11.CKA_SIGN],
["CKA_VERIFY", PyKCS11.CKA_VERIFY],
["CKA_ID", PyKCS11.CKA_ID],
["CKA_MODULUS", PyKCS11.CKA_MODULUS],
["CKA_MODULUS", PyKCS11.CKA_MODULUS],
["CKA_MODULUS_BITS", PyKCS11.CKA_MODULUS_BITS],
["CKA_PUBLIC_EXPONENT", PyKCS11.CKA_PUBLIC_EXPONENT],
["CKA_PRIVATE_EXPONENT", PyKCS11.CKA_PRIVATE_EXPONENT],
]
I'm getting an unhashable type: 'list' TypeError when trying to dump the attributes on the following block:
print "Dumping attributes:"
for q, a in zip(all_attributes, attributes):
if a == None:
# undefined (CKR_ATTRIBUTE_TYPE_INVALID) attribute
continue
if q == PyKCS11.CKA_CLASS:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKO[a], a)
elif q == PyKCS11.CKA_CERTIFICATE_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKC[a], a)
elif q == PyKCS11.CKA_KEY_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKK[a], a)
elif session.isBin(q):
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print dump(''.join(map(chr, a)), 16),
elif q == PyKCS11.CKA_SERIAL_NUMBER:
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print hexdump(a, 16),
else:
print format_normal % (PyKCS11.CKA[q], a)
This line specifically is generating the error:
if q == PyKCS11.CKA_CLASS:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKO[a], a)
I understand that you can't use a list as the key in a dict, since dict keys need to be immutable. How would I use a tuple in this situation?
回答1:
(This answer was put together in the context of your other questions)
To read attributes of a PKCS#11 object o
you can use the following code:
# List which attributes you want to read
attributeIds = [
CKA_ENCRYPT,
CKA_CLASS,
CKA_DECRYPT,
CKA_SIGN,
CKA_VERIFY,
CKA_ID,
CKA_MODULUS,
CKA_MODULUS_BITS,
CKA_PUBLIC_EXPONENT,
CKA_PRIVATE_EXPONENT
]
# Read them
attributeValues = session.getAttributeValue(o, attributeIds)
# Print them (variant 1 -- more readable)
for i in range(0,len(attributeIds)):
attributeName = CKA[attributeIds[i]]
print("Attribute %s: %s" % (attributeName, attributeValues[i]))
# Print them (variant 2 -- more consise)
for curAttrId, currAttrVale in zip(attributeIds,attributeValues):
attributeName = CKA[curAttrId]
print("Attribute %s: %s" % (attributeName, currAttrVale))
Some additional (random) notes:
the Session.getAttributeValue() method method requires a list of attribute ids. You are constructing a list of "lists containing Attribute name (string) and Attribute id (int)" -- without any conversion -- this can't work
the
CKA_PRIVATE_EXPONENT
attribute is sensitive for RSA private keys. You probably won't be able to read it unless theCKA_SENSITIVE
attribute is set toFalse
(see e.g. here)be sure to read only valid attributes for specific object (based on type, mechanism, sensitivity...)
the snippet above does not use the
PyKCS11.
prefix to reference PyKCS11 object members as it assumes they are imported withfrom PyKCS11 import *
directive (I am not enough into python to tell you which way is the good one)the attribute id <-> attribute name mapping is based on fact, that the
PKCS11.CKA
dictionary contains both string keys with int values and int keys with string keys (you can dump this dictionary yourself or check the source code)it might be much easier to dump the attributes with
print(o)
I would recommend reading relevant parts of the PKCS#11 standard
(you might get your answer faster if you referenced the origins of your thoughts)
Good luck!
来源:https://stackoverflow.com/questions/39535387/pykcs11-unhashable-list