PythonでのGOST暗号化によるPKCS#11トークンのサポート。パートII-Tokenクラスのオブジェクト

画像では 前の記事、pyp11モジュールは、提示されたCで書かれており、ロシアの暗号とPKCS#11トークンのサポートを提供します。この記事では、Pythonで記述されたスクリプトでのpyp11モジュールの機能の使用を簡素化するTokenクラスについて検討します TclOOで記述され、cryptoarmpkcsユーティリティで使用されるトークンクラスは、このクラスのプロトタイプとして使用されて いることに注意してください







トークンクラスのプロトタイプ
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
  }
}
      
      







Tokenクラスには、Pythonの他のクラスと同様 に、コンストラクタ、メソッド、およびデストラクタが含まれています。コンストラクタとデストラクタは同じメソッドですが、名前が事前定義されているだけです。コンストラクターの名前は__init__で、デストラクタの名前は__del__です。コンストラクタとデストラクタの宣言は省略できます。また、Tokenクラスでは、デストラクタ宣言を省略しますが、コンストラクタが必要になります。コンストラクターは、特定の属性を持つ特定のトークンのTokenクラスをインスタンス化します。



I.トークンクラスコンストラクター



したがって、Tokenクラスのコンストラクターは次のようになります。



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
#  ()  
      
      





(__init__メソッドの)コンストラクターのパラメーターは、(必須のselfに加えて)トークンライブラリーのハンドル(handlelp11)、トークンを配置するスロット番号(slottoken)、およびトークンのシリアル番号(シリアル番号)。



pkcs#11ライブラリのハンドル、スロット番号、およびそれらのトークンに関する情報を取得するには、次のスクリプトを使用できます。



#!/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()
      
      





ライブラリとスロットですべてが明確な場合は、トークンのシリアル番号で問題が発生する可能性があります。このパラメータが必要な理由と正確な理由ですが、たとえば、トークンラベルではありません。攻撃者が(または誤って)スロット内の1つのトークンを別のトークンに置き換えた場合、これが取得可能なトークンの基本であることをすぐに予約しましょう。さらに、トークンの異なるインスタンスが同じラベルを持つことができます。そして最後に、トークンがまだ初期化されていないか、所有者がトークンを再初期化する可能性があります。特に、トークンラベルを変更します。理論的には、シリアル番号でさえそのIDを保証するものではありません。トークンに関するすべての情報(シリアル番号、モデル、製造元)を考慮することが最適です。作成されたクラスのインスタンスの変数にトークンの引数を格納するのは、コンストラクターのタスクです。



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





このクラスで定義されているtokinfo()メソッドは、指定されたスロットに指定されたトークンが存在するかどうか確認します



tokinfoメソッドは2つの値を返します(上記のコンストラクターを参照):



#         
    ret, stat = self.tokinfo()
      
      





最初の変数(ret)にはメソッド実行の結果が含まれ、2番目の変数(stat)にはメソッドの実行がどのように終了したかに関する情報が含まれます。2番目の変数が空の場合、tokinfoメソッドは成功しました。2番目の変数が空でない場合、メソッドはエラーで終了しています。エラー情報はこの変数に含まれます。self.tokinfoメソッドの実行中にエラーが発生すると、コンストラクターはそれを戻りコード変数に書き込みます。



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





オブジェクト(クラスインスタンス)を作成した後、returncode変数の値をチェックして、指定したトークンのオブジェクトが作成されていることを確認する必要があります。



#!/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()
#  
. . .
      
      





オブジェクトの作成中にエラーが検出された場合は、次のオブジェクトを破棄することをお勧めします。



del < >
      
      





II。Tokenクラスのメソッドアーキテクチャ



メソッドを作成する際の主な原則は、例外処理はメソッド内にあり、例外(エラー)に関する情報はテキスト形式で返されるというものでした。これに基づいて、すべてのメソッドは2つの値を返します。実際の実行結果とエラーに関する情報です。エラーがない場合、2番目の値は空です。コンストラクターでtokinfoメソッドを使用してこれをすでに見ました。そして、これがtokinfoメソッド自体のコードです。



  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)
      
      





Tokenクラスの完全な説明はここにあります。
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)

      
      







Tokenクラスを使用してpyp11モジュールおよび同様の演算子の機能を使用することを検討しましょう。

後者の場合、トークンオブジェクトも作成する必要があります。



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





トークンを初期化することから始めましょう:



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





Tokenクラスを使用する場合の同様のコードは、次のようになります(オブジェクト識別子t1)。



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





次に、例外やエラーを処理せずに、pyp11モジュールのメイン演算子とTokenクラスのメソッドの間の対応を簡単に説明します。



<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>)

      
      





III。Tokenクラスを使用したpyp11モジュールの構築とインストール



Tokenクラスを使用してpyp11モジュール構築および インストールすることは、最初の部分で説明したものと同じです。



したがって、アーカイブダウンロードして 解凍します。PythonPKCS11フォルダーに移動し、インストールコマンドを実行します。



python3 setup.py install
      
      





モジュールをインストールした後、testsフォルダーに移動し、pyp11モジュールのテストを実行します。

Tokenクラスをテストするには、test / classtokenフォルダーに移動します。



pyp11モジュールとTokenクラスをスクリプトに接続するには、次の演算子を追加するだけです。



import pyp11
from Token import Token
      
      





IV。結論



近い将来、記事の3番目の部分が表示され、PyKCS11プロジェクトにロシアの暗号化のサポートを追加する方法が説明されます



PSありがとうと言いたい svyatikov Windowsプラットフォームでのプロジェクトのテストを支援してくれました。



All Articles