Attribute Type Invalid PyKCS11

1

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?

python
encryption
digital-signature
pkcs#11
hsm
asked on Stack Overflow Aug 10, 2016 by DJ2 • edited Oct 14, 2016 by vlp

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0