I have python script that essentially mirrors what this Attribute Dump achieves. In my slot number 2 I have a smart card that is recognized by a card reader. The card contains an RSA keypair and an x509 cert, that can be displayed using openssl. There is no problem with the device reader because the session is opened and proper vendor information is displayed, along with [1] object found. While trying to get all the attributes available in attempt to sign a message using SHA1, I'm receiving an CKR_ATTRIBUTE_TYPE_INVALID exception. I'm not sure where the bad attribute types occures and I've tried to locate the culprit for quite some time, to no avail.
print "Found %d objects: %s" % (len(objects), [x.value() for x in objects])
#-----------------------------CUTOFF FOR BAD ATTRIBUTE TYPE----------------------------
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],
]
for o in objects:
print
print (red + "==================== Object: %d ====================" + normal) % o.value()
attributes = session.getAttributeValue(o, all_attributes)
attrDict = dict(zip(all_attributes, attributes))
if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE \
and attrDict[PyKCS11.CKA_KEY_TYPE] == PyKCS11.CKK_RSA:
m = attrDict[PyKCS11.CKA_MODULUS]
e = attrDict[PyKCS11.CKA_PUBLIC_EXPONENT]
if m and e:
mx = eval('0x%s' % ''.join(chr(c) for c in m).encode('hex'))
ex = eval('0x%s' % ''.join(chr(c) for c in e).encode('hex'))
if sign:
try:
toSign = "12345678901234567890" # 20 bytes, SHA1 digest
print "* Signing with object 0x%08X following data: %s" % (o.value(), toSign)
signature = session.sign(o, toSign)
s = ''.join(chr(c) for c in signature).encode('hex')
sx = eval('0x%s' % s)
print "Signature:"
print hexdump(''.join(map(chr, signature)), 16)
if m and e:
print "Verifying using following public key:"
print "Modulus:"
print hexdump(''.join(map(chr, m)), 16)
print "Exponent:"
print hexdump(''.join(map(chr, e)), 16)
decrypted = pow(sx, ex, mx) # RSA
print "Decrypted:"
d = hexx(decrypted).decode('hex')
print hexdump(d, 16)
if toSign == d[-20:]:
print "*** signature VERIFIED!\n"
else:
print "*** signature NOT VERIFIED; decrypted value:"
print hex(decrypted), "\n"
else:
print "Unable to verify signature: MODULUS/PUBLIC_EXP not found"
except:
print "Sign failed, exception:", str(sys.exc_info()[1])
if decrypt:
if m and e:
try:
toEncrypt = "12345678901234567890"
# note: PKCS1 BT2 padding should be random data,
# but this is just a test and we use 0xFF...
padded = "\x00\x02%s\x00%s" % ("\xFF" * (128 - (len(toEncrypt)) - 3), toEncrypt)
print "* Decrypting with 0x%08X following data: %s" % (o.value(), toEncrypt)
print "padded:\n", dump(padded, 16)
encrypted = pow(eval('0x%sL' % padded.encode('hex')), ex, mx) # RSA
encrypted1 = hexx(encrypted).decode('hex')
print "encrypted:\n", dump(encrypted1, 16)
decrypted = session.decrypt(o, encrypted1)
decrypted1 = ''.join(chr(i) for i in decrypted)
print "decrypted:\n", dump(decrypted1, 16)
if decrypted1 == toEncrypt:
print "decryption SUCCESSFULL!\n"
else:
print "decryption FAILED!\n"
except:
print "Decrypt failed, exception:", str(sys.exc_info()[1])
else:
print "ERROR: Private key don't have MODULUS/PUBLIC_EXP"
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)
The bad entry type in the attribute list is somewhere in the code above. I'm not sure which is causing it to fail. I have confused myself after learning the LowLevel API first.
Slot no: 2
slotDescription: ONMIKEY CardMan 3111
manufacturerID: OMNIKEY
TokenInfo
label: SSS Card 001
manufacturerID: Siemens
model: Siem. OS V4.x
Opened session 0x00020001
Found 1 objects: [1]
==================== Object: 1 ====================
Error: CKR_ATTRIBUTE_TYPE_INVALID (0x00000012)
Is the best approach to construct my own attribute list?
User contributions licensed under CC BY-SA 3.0