Skip to content

Instantly share code, notes, and snippets.

@DnaX
Created March 9, 2012 12:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DnaX/2006262 to your computer and use it in GitHub Desktop.
Save DnaX/2006262 to your computer and use it in GitHub Desktop.
CNS smart card PersonalData extractor (by PKCS#11 library)
#!/usr/bin/env python
# Uses OpenSC pkcs11 generic library and pkcs11 python wrapper
# Print personal data from che italian CNS smart card (new health card)
from PyKCS11 import LowLevel
import sys
def getPersonalData(p11, slot):
session = LowLevel.CK_SESSION_HANDLE()
rv = p11.C_OpenSession(slot, LowLevel.CKF_SERIAL_SESSION, session)
SearchResult = LowLevel.ckobjlist(10)
SearchTemplate = LowLevel.ckattrlist(2)
SearchTemplate[0].SetString(LowLevel.CKA_LABEL, "EF_DatiPersonali")
SearchTemplate[1].SetBool(LowLevel.CKA_TOKEN, True)
print "\tSearch for EF_DatiPersonali object..."
rv = p11.C_FindObjectsInit(session, SearchTemplate)
#print "C_FindObjectsInit: rv=", hex(rv)
if (rv != LowLevel.CKR_OK):
print "\t\x1b[31mEF_DatiPersonali data object not found on smart card\x1b[0m"
return
rv = p11.C_FindObjects(session, SearchResult)
#print "C_FindObjects: rv=", hex(rv)
if (rv != LowLevel.CKR_OK):
sys.exit(1)
#print "C_FindObjectsFinal: rv=", hex(p11.C_FindObjectsFinal(session))
for x in SearchResult:
#print "object handle: 0x%08X" % x.value()
valTemplate = LowLevel.ckattrlist(3)
valTemplate[0].SetType(LowLevel.CKA_LABEL)
valTemplate[1].SetType(LowLevel.CKA_CLASS)
valTemplate[2].SetType(LowLevel.CKA_VALUE)
# please note the dobule call to C_GetAttributeValue:
# first call to get data size and second call to actually get the datp11.
rv = p11.C_GetAttributeValue(session, x, valTemplate)
#print "C_GetAttributeValue(1): rv=", hex(rv)
if (rv == LowLevel.CKR_OK):
rv = p11.C_GetAttributeValue(session, x, valTemplate)
if (rv == LowLevel.CKR_OK):
#print "\tCKA_LABEL: ", valTemplate[0].GetString()
#print "\tCKA_CLASS: ", valTemplate[1].GetNum()
#print "\tCKA_VALUE: ", valTemplate[2].GetString()
fields = ["Ente emettitore", "Data emissione", "Data scadenza", "Cognome", "Nome", "Data nascita", "Sesso", "Statura", "Codice fiscale", "Cittadinanza", "Comune nascita", "Stato estero nascita", "Estremi atto nascita", "Comune residenza", "Indirizzo residenza", "Validita espatrio"]
data = valTemplate[2].GetString()
curField = 0
i = 6
filledFields = {}
while i < len(data):
if data[i] == '\x00':
break
fieldLen = int(data[i:i+2], 16)
#print "Length: 0x%s (%d)" % (data[i:i+2], fieldLen)
i += 2
if curField == 1 or curField == 2 or curField == 5:
fieldValue = data[i:i+2] + '/' + data[i+2:i+4] + '/' + data[i+4:i+8]
else:
fieldValue = data[i:i+fieldLen]
print "\x1b[34m", fields[curField] + ":\x1b[0m", fieldValue
filledFields[fields[curField]] = fieldValue
i += fieldLen
curField += 1
p11.C_CloseSession(session)
def pkcs11_init():
lib = "/usr/lib/opensc-pkcs11.so" # place here your PKCS#11 library
p11 = LowLevel.CPKCS11Lib()
info = LowLevel.CK_INFO()
slotList = LowLevel.ckintlist()
SlotInfos = LowLevel.CK_SLOT_INFO()
TokenInfos = LowLevel.CK_TOKEN_INFO()
print "Loading and initializing OpenSC PKCS#11 library..."
loadRes = p11.Load(lib, True)
if not loadRes:
print "Error on loading PKCS#11 library"
sys.exit(1)
# listing only slots with a token inside.
rv = p11.C_GetSlotList(True, slotList)
if (rv != LowLevel.CKR_OK):
sys.exit(1)
if len(slotList) == 0:
print "Please insert a token in any slot"
sys.exit(1)
print "Slots found: ", len(slotList)
for slot in slotList:
rv = p11.C_GetSlotInfo(slot, SlotInfos)
print "\nSlot " + str(slot) + ": \x1b[1;33m" + SlotInfos.GetSlotDescription() + "\x1b[0m"
rv = p11.C_GetTokenInfo(1, TokenInfos)
print "\tModel: " + TokenInfos.GetModel(), " Details:", TokenInfos.GetManufacturerID()
getPersonalData(p11, slot)
p11.C_Finalize()
p11.Unload()
pkcs11_init()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment