Dukungan untuk token PKCS # 11 dengan kriptografi GOST dengan Python. Bagian II - Objek kelas Token

gambarPada artikel sebelumnya , modul pyp11 disajikan, ditulis dalam C dan memberikan dukungan token PKCS # 11 dengan kriptografi Rusia. Artikel ini akan mempertimbangkan kelas Token, yang akan menyederhanakan penggunaan fungsionalitas modul pyp11 dalam skrip yang ditulis dengan Python. Perhatikan bahwa kelas token, yang ditulis dalam TclOO dan digunakan dalam utilitas cryptoarmpkcs , diambil sebagai prototipe kelas ini :







Prototipe kelas token
oo::class create token {
  variable libp11
  variable handle
  variable infotok
  variable pintok
  variable nodet
#
  constructor {handlelp11 labtoken slottoken} {
    global pass
    global yespas
    set handle $handlelp11
    set slots [pki::pkcs11::listslots $handle]
    array set infotok []
    foreach slotinfo $slots {
      set slotflags [lindex $slotinfo 2]
      if {[lsearch -exact $slotflags TOKEN_PRESENT] != -1} {
        if {[string first $labtoken [lindex $slotinfo 1]] != -1} {
          set infotok(slotlabel) [lindex $slotinfo 1]
          set infotok(slotid) [lindex $slotinfo 0]
          set infotok(slotflags) [lindex $slotinfo 2]
          set infotok(token) [lindex $slotinfo 3]
          #  
          break
        }
      }
    }
    #    
    if {[llength [array names infotok]] == 0 } {
      error "Constructor: Token not present for library   : $handle"
    }
    #  
    set nodet [dict create pkcs11_handle $handle]
    dict set nodet pkcs11_slotid $infotok(slotid)
    set tit " PIN-   $infotok(slotlabel)"
    set xa [my read_password $tit]
    if {$xa == "no"} {
      error "   PIN   $infotok(slotlabel)"
    }
    set pintok $pass
    set pass ""
    set rr [my login ]
    if { $rr == 0 } {
      unset pintok
      error " PIN-  $infotok(slotlabel)."
    } elseif {$rr == -1} {
      unset pintok
      error " ."
    }
    my logout
  }
# 
  method infoslot {} {
    return [array get infotok]
  }
  method listcerts {} {
    array set lcerts []
    set certsder [pki::pkcs11::listcertsder $handle $infotok(slotid)]
    # 
    foreach lc $certsder {
      array set derc $lc
      set lcerts($derc(pkcs11_label)) [list $derc(cert_der) $derc(pkcs11_id)]
      #parray derc
    }
    return [array get lcerts]
  }
  method read_password {tit} {
    global yespas
    global pass
    set tit_orig "$::labpas"
    if {$tit != ""} {
      set ::labpas "$tit"
    }
    tk busy hold ".st.fr1"
    tk busy hold ".st.fr3"
    #	place .topPinPw -in .st.fr1.fr2_certs.labCert  -relx 1.0 -rely 3.0 -relwidth 3.5
    place .topPinPw -in .st.labMain  -relx 0.35 -rely 5.0 -relwidth 0.30
    set yespas ""
    focus .topPinPw.labFrPw.entryPw
    vwait yespas
    catch {tk busy forget ".st.fr1"}
    catch {tk busy forget ".st.fr3"}
    if {$tit != ""} {
      set ::labpas "$tit_orig"
    }
    place forget .topPinPw
    return $yespas
  }
  unexport read_password
  method rename {type ckaid newlab} {
    if {$type != "cert" && $type != "key" && $type != "all"} {
      error "Bad type for rename "
    }
    set uu $nodet
    lappend uu "pkcs11_id"
    lappend uu $ckaid
    lappend uu "pkcs11_label"
    lappend uu $newlab
    if { [my login ] == 0 } {
      unset uu
      return 0
    }
    pki::pkcs11::rename $type $uu
    my logout
    return 1
  }
  method changeid {type ckaid newid} {
    if {$type != "cert" && $type != "key" && $type != "all"} {
      error "Bad type for changeid "
    }
    set uu $nodet
    lappend uu "pkcs11_id"
    lappend uu $ckaid
    lappend uu "pkcs11_id_new"
    lappend uu $newid
    if { [my login ] == 0 } {
      unset uu
      return 0
    }
    pki::pkcs11::rename $type $uu
    my logout
    return 1
  }
  method delete {type ckaid} {
    if {$type != "cert" && $type != "key" && $type != "all" && $type != "obj"} {
      error "Bad type for delete"
    }
    set uu $nodet
    lappend uu "pkcs11_id"
    lappend uu $ckaid
    my login
    ::pki::pkcs11::delete $type $uu
    my logout
    return 1
  }
  method deleteobj {hobj} {
    set uu $nodet
    lappend uu "hobj"
    lappend uu $hobj
#tk_messageBox -title "class deleteobj" -icon info -message "hobj: $hobj\n" -detail "$uu"
    return [::pki::pkcs11::delete obj $uu ]
  }
  method listmechs {} {
    set llmech [pki::pkcs11::listmechs $handle $infotok(slotid)]
    return $llmech
  }
  method pubkeyinfo {cert_der_hex} {
    array set linfopk [pki::pkcs11::pubkeyinfo $cert_der_hex $nodet]
    return [array get linfopk]
  }
  method listobjects {type} {
    if {$type != "cert" && $type != "pubkey" && $type != "privkey" && $type != "all" && $type != "data"} {
      error "Bad type for listobjects "
    }
    set allobjs [::pki::pkcs11::listobjects $handle $infotok(slotid) $type]
    return $allobjs
  }
  method importcert {cert_der_hex cka_label} {
    set uu $nodet
    dict set uu pkcs11_label $cka_label
    if {[catch {set pkcs11id [pki::pkcs11::importcert $cert_der_hex $uu]} res] } {
      error "Cannot import this certificate:$res"
      #          return 0
    }
    return $pkcs11id
  }
  method login {} {
    set wh 1
    set rl -1
    while {$wh == 1} {
      if {[catch {set rl [pki::pkcs11::login $handle $infotok(slotid) $pintok]} res]} {
        if {[string first "SESSION_HANDLE_INVALID" $res] != -1} {
          pki::pkcs11::closesession $handle
          continue
        } elseif {[string first "TOKEN_NOT_PRESENT" $res] != -1} {
          set wh 0
          continue
        }
      }
      break
    }
    if {$wh == 0} {
      return -1
    }
    return $rl
  }
  method logout {} {
    return [pki::pkcs11::logout $handle $infotok(slotid)]
  }
  method keypair {typegost parkey} {
    my login
    set skey [pki::pkcs11::keypair $typegost $parkey $nodet]
    my logout
    return $skey
  }
  method digest {typehash source} {
    return [pki::pkcs11::digest $typehash $source $nodet]
  }
  method signkey {ckm digest hobj_priv} {
    set uu $nodet
    dict set uu hobj_privkey $hobj_priv
    my login
    set ss [pki::pkcs11::sign $ckm $digest $uu]
    my logout
    return $ss
  }
  method signcert {ckm digest pkcs11_id} {
    set uu $nodet
    dict set uu pkcs11_id $pkcs11_id
    my login
    set ss  [pki::pkcs11::sign $ckm $digest $uu]
    my logout
    return $ss
  }
  method verify {digest signature asn1pubkey} {
    set uu $nodet
    dict set uu pubkeyinfo $asn1pubkey
    return [pki::pkcs11::verify $digest $signature $uu]
  }
  method tokenpresent {} {
    set slots [pki::pkcs11::listslots $handle]
    foreach slotinfo $slots {
      set slotid [lindex $slotinfo 0]
      set slotlabel [lindex $slotinfo 1]
      set slotflags [lindex $slotinfo 2]
      if {[lsearch -exact $slotflags TOKEN_PRESENT] != -1} {
        if {infotok(slotlabel) == $slotlabel && $slotid == $infotok(slotid)} {
          return 1
        }
      }
    }
    return 0
  }
  method setpin {type tpin newpin} {
    if {$type != "user" && $type != "so"} {
      return 0
    }
    if {$type == "user"} {
      if {$tpin != $pintok} {
        return 0
      }
    }
    set ret [::pki::pkcs11::setpin  $handle $infotok(slotid) $type $tpin $newpin]
    if {$type == "user"} {
      if {$ret} {
        set pitok $newpin
      }
    }
    return $ret
  }
  method inituserpin {sopin upin} {
    set ret [::pki::pkcs11::inituserpin $handle $infotok(slotid) $sopin $upin]
    return $ret
  }
  method importkey {uukey} {
    set uu $nodet
    append uu " $uukey"
    my login
    if {[catch {set impkey [pki::pkcs11::importkey $uu ]} res] } {
        set impkey 0
    }
    my logout
    return $impkey
  }
#
  destructor {
    variable handle
    if {[info exists pintok]} {
      my login
    }
    #	    ::pki::pkcs11::unloadmodule  $handle
  }
}
      
      







Kelas Token, seperti kelas apa pun di Python , termasuk konstruktor, metode, dan destruktor. Konstruktor dan destruktor adalah metode yang sama, hanya dengan nama yang telah ditentukan. Konstruktornya bernama __init__, dan destruktornya bernama __del__. Deklarasi konstruktor dan destruktor dapat dihilangkan. Dan di kelas Token, kami akan menghilangkan deklarasi destruktor, tetapi konstruktor akan dibutuhkan. Konstruktor akan membuat instance kelas Token untuk token tertentu dengan atribut tertentu.



I. Konstruktor kelas token



Jadi, konstruktor kelas Token terlihat seperti ini:



import sys
import pyp11
class Token:
  def __init__ (self, handlelp11, slottoken, serialnum):
    flags = ''
    self.pyver = sys.version[0]
    if (self.pyver == '2'):
        print ('  python3')
        quit()
# handle  PKCS#11
    self.handle = handlelp11
#    
    self.slotid = slottoken
#   
    self.sn = serialnum
#         
    ret, stat = self.tokinfo()
#  
    if (stat != ''):
#   
        self.returncode = stat
        return
#  ()  
      
      





Parameter konstruktor (dari metode __init__) adalah (selain diri wajib) pegangan perpustakaan token (handlelp11), nomor slot (slottoken) di mana token harus ditempatkan, dan nomor seri token ( serialnum).



Untuk mendapatkan handle pkcs # 11 library, nomor slot dan informasi tentang token di dalamnya, Anda dapat menggunakan script berikut:



#!/usr/bin/python3
import sys
import pyp11
from Token import Token
def listslots (handle):
    slots = pyp11.listslots(aa)
    i = 0
    lslots = []
    for v in slots:
        for f in v[2]:
    	    if (f == 'TOKEN_PRESENT'):
                i = 1
                lslots.append(v)
                break
    i += 1
    return (lslots)
#  Linux
# 
lib = '/usr/local/lib64/libls11sw2016.so'
# 
#lib = '/usr/local/lib64/libls11cloud.so'
# 
#lib = '/usr/local/lib64/librtpkcs11ecp_2.0.so'
#  Windows
#lib='C:\Temp\ls11sw2016.dll'
try:
#       handle ( )
    aa = pyp11.loadmodule(lib)
    print('Handle  ' + lib + ': ' + aa)
except:
    print('Except load lib: ')
    e = sys.exc_info()[1]
    e1 = e.args[0]
# 
    print (e1)
    quit()
# 
slots = listslots(aa)
i = 0
for v in slots:
    for f in v[2]:
        if (f == 'TOKEN_PRESENT'):
    	    if (i == 0):
    	        print ('\n    \n')
    	    it = v[3]
    	    print ('slotid=' + str(v[0]))
    	    print ('\tFlags=' + str(v[2]))
    	    print ('\tLabel="' + it[0].strip() + '"')
    	    print ('\tManufacturer="' + it[1].strip() + '"')
    	    print ('\tModel="' + it[2].strip() + '"')
    	    print ('\tSerialNumber="' + it[3].strip() + '"')
    	    i = 1
    	    break
    i += 1
pyp11.unloadmodule(aa)
if (i == 0):
    print ('    .     ')
quit()
      
      





Jika semuanya jelas dengan pustaka dan slot, maka pertanyaan mungkin muncul dengan nomor seri token - mengapa parameter ini diperlukan dan mengapa tepatnya, tetapi, misalnya, bukan label token. Mari segera buat reservasi bahwa ini penting untuk token yang dapat diambil, ketika penyerang (atau tidak sengaja) mengganti satu token di slot dengan token lain. Selain itu, contoh token yang berbeda dapat memiliki label yang sama. Dan terakhir, token mungkin belum diinisialisasi atau pemilik akan menginisialisasi ulang, khususnya, mengubah label token. Secara teori, bahkan nomor seri tidak menjamin identitasnya; optimal untuk memperhitungkan semua informasi tentang token (nomor seri, model, pabrikan). Ini adalah tugas konstruktor untuk menyimpan argumen token dalam variabel dari instance kelas yang dibuat:



...
# handle  PKCS#11
    self.handle = handlelp11
#    
    self.slotid = slottoken
#   
    self.sn = serialnum
...
      
      





Metode tokinfo () yang ditentukan dalam kelas ini memeriksa keberadaan token yang ditentukan dalam slot yang ditentukan .



Metode tokinfo mengembalikan dua nilai (lihat di atas dalam konstruktor):



#         
    ret, stat = self.tokinfo()
      
      





Variabel pertama (ret) berisi hasil dari eksekusi metode, dan yang kedua (stat) berisi informasi tentang bagaimana eksekusi metode berakhir. Jika variabel kedua kosong, maka metode tokinfo berhasil. Jika variabel kedua tidak kosong, maka metode diakhiri dengan kesalahan. Informasi kesalahan akan ada di variabel ini. Ketika kesalahan ditemukan selama eksekusi metode self.tokinfo, konstruktor menuliskannya ke variabel kode kembali:



#         
    ret, stat = self.tokinfo()
#  
    if (stat != ''):
#      returncode
        self.returncode = stat
        return
      
      





Setelah membuat objek (instance kelas), Anda perlu memeriksa nilai variabel kode kembali untuk memastikan bahwa objek untuk token yang ditentukan telah dibuat:



#!/usr/bin/python3
import sys
import pyp11
from Token import Token
# 
# 
lib = '/usr/local/lib64/librtpkcs11ecp_2.0.so'
try:
    aa = pyp11.loadmodule(lib)
except:
    e = sys.exc_info()[1]
    e1 = e.args[0]
    print (e1)
    quit()
#  
sn = '9999999999999999'
slot = 110
#  
t1 = Token(aa, slot, sn)
#  returncode
if (t1.returncode != ''):
#   
    print (t1.returncode)
# 
    del t1
# 
    quit()
#  
. . .
      
      





Jika kesalahan terdeteksi saat membuat objek, maka disarankan untuk menghancurkan objek ini:



del < >
      
      





II. Arsitektur metode di kelas Token



Prinsip utama saat menulis metode adalah bahwa penanganan pengecualian ada di dalam metode, dan informasi tentang pengecualian (kesalahan) dikembalikan dalam bentuk teks. Berdasarkan ini, semua metode mengembalikan dua nilai: hasil eksekusi aktual dan informasi tentang kesalahan. Jika tidak ada kesalahan, maka nilai kedua kosong. Kami telah melihat ini menggunakan metode tokinfo di konstruktor. Dan berikut adalah kode untuk metode tokinfo itu sendiri:



  def tokinfo(self):
    status = ''
#  
    try:
        slots = pyp11.listslots(self.handle)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        dd = ''
        status = e1
        return (dd, status)
    status = ''
#      
# 
    for v in slots:
#  
            if (v[0] != self.slotid):
                status = " "
                continue
            self.returncode = ''
#   
            self.flags = v[2]
#    
            if (self.flags.count('TOKEN_PRESENT') !=0):
#   
                tokinf = v[3]
                sn = tokinf[3].strip()
                if (self.sn != sn):
                    status = '  =\"' + sn + '\"     \"' + self.sn + '\"'
                    dd = ''
                    return (dd, status)
                status = ''
                break
            else:
                dd = ''
                status = "   "
                return (dd, status)
    tt = tokinf
    dd = dict(Label=tt[0].strip())
    dd.update(Manufacturer=tt[1].strip())
    dd.update(Model=tt[2].strip())
    dd.update(SerialNumber=tt[3].strip())
    self.infotok = dd
# 
    return (dd, status)
      
      





Penjelasan lengkap tentang kelas Token dapat ditemukan di sini.
import sys
import pyp11
class Token:
  def __init__ (self, handlelp11, slottoken, serialnum):
    flags = ''
    self.pyver = sys.version[0]
    if (self.pyver == '2'):
        print ('  python3')
        quit()
# handle  PKCS#11
    self.handle = handlelp11
#    
    self.slotid = slottoken
#   
    self.sn = serialnum
#          
    ret, stat = self.tokinfo()
#  
    if (stat != ''):
#   
        self.returncode = stat
        return
#  ()  
  def tokinfo(self):
    status = ''
#  
    try:
        slots = pyp11.listslots(self.handle)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        dd = ''
        status = e1
        return (dd, status)
    status = ''
#      
# 
    for v in slots:
#  
            if (v[0] != self.slotid):
                status = " "
                continue
            self.returncode = ''
#   
            self.flags = v[2]
#    
            if (self.flags.count('TOKEN_PRESENT') !=0):
#   
                tokinf = v[3]
                sn = tokinf[3].strip()
                if (self.sn != sn):
                    status = '  =\"' + sn + '\"     \"' + self.sn + '\"'
                    dd = ''
                    return (dd, status)
                status = ''
                break
            else:
                dd = ''
                status = "   "
                return (dd, status)
    tt = tokinf
    dd = dict(Label=tt[0].strip())
    dd.update(Manufacturer=tt[1].strip())
    dd.update(Model=tt[2].strip())
    dd.update(SerialNumber=tt[3].strip())
    self.infotok = dd
    return (dd, status)
  def listcerts(self):
    try:
        status = ''
        lcerts = pyp11.listcerts(self.handle, self.slotid)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        lcerts = ''
        status = e1
    return (lcerts, status)
  def listobjects(self, type1, value = '' ):
    try:
        status = ''
        if (value == ''):
    	    lobjs = pyp11.listobjects(self.handle, self.slotid, type1)
        else:
    	    lobjs = pyp11.listobjects(self.handle, self.slotid, type1, value)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        lobjs = ''
        status = e1
    return (lobjs, status)
  def rename(self, type, pkcs11id, label):
    try:
        status = ''
        dd = dict(pkcs11_id=pkcs11id, pkcs11_label=label)
        ret = pyp11.rename(self.handle, self.slotid, type, dd)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        ret = ''
        status = e1
    return (ret, status)
  def changeckaid(self, type, pkcs11id, pkcs11idnew):
    try:
        status = ''
        dd = dict(pkcs11_id=pkcs11id, pkcs11_id_new=pkcs11idnew)
        ret = pyp11.rename(self.handle, self.slotid, type, dd)
    except:
#   
        e = sys.exc_info()[1]
        e1 = e.args[0]
        ret = ''
        status = e1
    return (ret, status)
  def login(self, userpin):
    try:
        status = ''
        bb = pyp11.login (self.handle, self.slotid, userpin)
    except:
        e = sys.exc_info()[1]
        e1 = e.args[0]
        bb = 0
        status = e1
    return (bb, status)
  def logout(self):
    try:
        status = ''
        bb = pyp11.logout (self.handle, self.slotid)
    except:
        e = sys.exc_info()[1]
        e1 = e.args[0]
        bb = 0
        status = e1
    return (bb, status)
  def keypair(self, typek, paramk, labkey):
#  
    gost2012_512 = ['1.2.643.7.1.2.1.2.1', '1.2.643.7.1.2.1.2.2', '1.2.643.7.1.2.1.2.3']
    gost2012_256 = ['1.2.643.2.2.35.1', '1.2.643.2.2.35.2',  '1.2.643.2.2.35.3',  '1.2.643.2.2.36.0', '1.2.643.2.2.36.1', '1.2.643.7.1.2.1.1.1', '1.2.643.7.1.2.1.1.2', '1.2.643.7.1.2.1.1.3', '1.2.643.7.1.2.1.1.4']
    gost2001 = ['1.2.643.2.2.35.1', '1.2.643.2.2.35.2',  '1.2.643.2.2.35.3',  '1.2.643.2.2.36.0', '1.2.643.2.2.36.1']
# 
    typekey = ['g12_256', 'g12_512', 'gost2001']
    genkey = ''
    if (typek == typekey[0]):
    	gost = gost2012_256
    elif (typek == typekey[1]):
    	gost = gost2012_512
    elif (typek == typekey[2]):
    	gost = gost2001
    else:
    	status = '  '
    	return (genkey, status)
    if (gost.count(paramk) == 0) :
    	status = '  '
    	return (genkey, status)
    try:
# ,   
    	status = ''
    	genkey = pyp11.keypair(self.handle, self.slotid, typek, paramk, labkey)
    except:
#    
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
    	print (e1)
#    
    	status = e1
    return (genkey, status)   
  def digest(self, typehash, source):
# 
    try:
        status = ''
        digest_hex = pyp11.digest (self.handle, self.slotid, typehash, source)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    
    	status = e1
    	digest_hex = ''
    return (digest_hex, status)
# 
  def sign(self, ckmpair, digest_hex, idorhandle):
#    CKA_ID  handle  
    try:
        status = ''
        sign_hex = pyp11.sign(self.handle, self.slotid, ckmpair, digest_hex, idorhandle)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    
    	status = e1
    	sign_hex = ''
    return (sign_hex, status)
# 
  def verify(self, digest_hex, sign_hex, pubkeyinfo):
#    CKA_ID  handle  
    try:
        status = ''
        verify = pyp11.verify(self.handle, self.slotid, digest_hex, sign_hex, pubkeyinfo)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	verify = 0
    	status = e1
    return (verify, status)
# 
  def inittoken(self, sopin, labtoken):
    try:
        status = ''
        dd = pyp11.inittoken (self.handle, self.slotid, sopin, labtoken)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = 0
    	status = e1
    return (dd, status)
#  PIN-
  def inituserpin(self, sopin, userpin):
    try:
        status = ''
        dd = pyp11.inituserpin (self.handle, self.slotid, sopin, userpin)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = 0
    	status = e1
    return (dd, status)
#  PIN-
  def changeuserpin(self, oldpin, newpin):
    try:
        status = ''
        dd = pyp11.setpin (self.handle, self.slotid, 'user', oldpin, newpin)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = 0
    	status = e1
    self.closesession ()
    return (dd, status)
  def closesession(self):
    try:
        status = ''
        dd = pyp11.closesession (self.handle)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = 0
    	status = e1
    return (dd, status)
  def parsecert(self, cert_der_hex):
    try:
        status = ''
        dd = pyp11.parsecert (self.handle, self.slotid, cert_der_hex)
    except:
#   
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = ''
    	status = e1
    return (dd, status)
  def importcert(self, cert_der_hex, labcert):
    try:
        status = ''
        dd = pyp11.importcert (self.handle, self.slotid, cert_der_hex, labcert)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = ''
    	status = e1
    return (dd, status)
  def delobject(self, hobject):
    try:
        status = ''
        hobjc = dict(hobj=hobject)
        dd = pyp11.delete(self.handle, self.slotid, 'obj', hobjc)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = ''
    	status = e1
    return (dd, status)
  def delete(self, type, pkcs11id):
    if (type == 'obj'):
        dd = ''
        status = 'delete for type obj use nethod delobject'
        return (dd, status)
    try:
        status = ''
        idobj = dict(pkcs11_id=pkcs11id)
        dd = pyp11.delete(self.handle, self.slotid, type, idobj)
    except:
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = ''
    	status = e1
    return (dd, status)
  def listmechs(self):
    try:
        status = ''
        dd = pyp11.listmechs (self.handle, self.slotid)
    except:
#     
    	e = sys.exc_info()[1]
    	e1 = e.args[0]
#    status
    	dd = ''
    	status = e1
    return (dd, status)

      
      







Mari pertimbangkan untuk menggunakan fungsionalitas modul pyp11 dan operator serupa menggunakan kelas Token.

Dalam kasus terakhir, perlu juga membuat objek token:



< > = Token(< >, < >, < >)
if (< >.returncode != ''):
   print('   :')
# 
   print(< >.returncode)
# 
   del < >
   quit()
      
      





Mari kita mulai dengan menginisialisasi token:



try:
    ret = pyp11.inittoken (< >, < >, <SO-PIN>, < >)
except:
#   
    e = sys.exc_info()[1]
    e1 = e.args[0]
    print (e1)
    quit()
      
      





Kode serupa saat menggunakan kelas Token terlihat seperti ini (pengidentifikasi objek t1):



ret, stat = t1.inittoken(<SO-PIN>, < >)
#  
if (stat != ''):
   print('   :')
# 
   print(stat)
   quit()  
      
      





Selanjutnya, kami hanya akan memberikan korespondensi antara operator utama modul pyp11 dan metode kelas Token tanpa menangani pengecualian dan kesalahan:



<handle> := <  pkcs11>
<slot> := <   >
<error> := <   >
<ret> := <  >
<cert_der_hex> := <  DER-  HEX->
=================================================
#  PIN-
<ret> = pyp11.inituserpin (<handle>, <slot>, <SO-PIN>, <USER-PIN>)
<ret>, <error> = < >.inituserpin (<SO-PIN>, <USER-PIN>)
# USER-PIN 
<ret> = pyp11.setpin (<handle>, <slot>, 'user', <USER-PIN >, <USER-PIN >)
<ret>, <error> = t1.changeuserpin (<USER-PIN >, <USER-PIN >)
# SO-PIN 
<ret> = pyp11.setpin (<handle>, <slot>, 'so', <SO-PIN >, <SO-PIN >)
<ret>, <error> = t1.changesopin (<SO-PIN >, <SO-PIN >)
#Login
<ret> = pyp11.login (<handle>, <slot>, <USER-PIN>)
<ret>, <error> = t1.login (<USER-PIN>)
#Logout
<ret> = pyp11.logout (<handle>, <slot>)
<ret>, <error> = t1.logout ()
# 
<ret> = pyp11.closesession (<handle>)
<ret>, <error> = t1.closesession ()
#   
<ret> = pyp11.listcerts (<handle>, <slot>)
<ret>, <error> = t1.listcerts ()
#   
<ret> = pyp11.listobjects (<handle>, <slot>, <'cert' | 'pubkey' | 'privkey' | 'data' | 'all'> [, 'value'])
<ret>, <error> = t1.listobjects (<'cert' | 'pubkey' | 'privkey' | 'data' | 'all'> [, 'value'])
# 
<ret> = pyp11.parsecert (<handle>, <slot>, <cert_der_hex>)
<ret>, <error> = t1.parsecert(<cert_der_hex>)
# 
<ret> = pyp11.importcert (<handle>, <slot>, <cert_der_hex>, < >)
<ret>, <error> = t1.importcert(<cert_der_hex>, < >)
# 
<ret> = pyp11.digest (<handle>, <slot>, < >, <>)
<ret>, <error> = t1.digest(< >, <>)
#  
<ret> = pyp11.digest (<handle>, <slot>, < >, <  >, <CKA_ID | handle  >)
<ret>, <error> = t1.digest(< >, <  >, <CKA_ID | handle  >)
#  
<ret> = pyp11.verify (<handle>, <slot>, <  >, <>, <asn1- subjectpublickeyinfo  hex>)
<ret>, <error> = t1.verify(<  >, <>, <asn1- subjectpublickeyinfo  hex>)
#  
<ret> = pyp11.keypair (<handle>, <slot>, < >, <OID >, <CKA_LABEL>)
<ret>, <error> = t1.keypair(< >, <OID >, <CKA_LABEL>)

      
      





AKU AKU AKU. Membangun dan menginstal modul pyp11 dengan kelas Token



Membangun dan menginstal modul pyp11 dengan kelas Token tidak berbeda dengan yang dijelaskan di bagian pertama.



Jadi, unduh arsip dan buka kemasannya. Kami masuk ke folder PythonPKCS11 dan menjalankan perintah instalasi:



python3 setup.py install
      
      





Setelah menginstal modul, buka folder tes dan jalankan tes untuk modul pyp11.

Untuk menguji kelas Token, buka folder test / classtoken.



Untuk menghubungkan modul pyp11 dan kelas Token ke skrip, cukup tambahkan operator berikut:



import pyp11
from Token import Token
      
      





IV. Kesimpulan



Dalam waktu dekat, bagian ketiga dari artikel akan muncul, yang akan memberi tahu Anda cara menambahkan dukungan untuk kriptografi Rusia ke proyek PyKCS11 .



PS Saya ingin mengucapkan terima kasih svyatikov.dll untuk membantu menguji proyek pada platform Windows.



All Articles