1+ from __future__ import annotations
2+
13from datetime import datetime
4+ from enum import IntEnum
25from struct import Struct
6+ from typing import Any , Callable , Final
37
4- from pkcs11 .constants import (
5- Attribute ,
6- CertificateType ,
7- MechanismFlag ,
8- ObjectClass ,
9- )
8+ from pkcs11 .constants import Attribute , CertificateType , MechanismFlag , ObjectClass
109from pkcs11 .mechanisms import KeyType , Mechanism
1110
11+ # Type aliases for pack/unpack function pairs
12+ PackFunc = Callable [[Any ], bytes ]
13+ UnpackFunc = Callable [[bytes ], Any ]
14+ Handler = tuple [PackFunc , UnpackFunc ]
15+
1216# (Pack Function, Unpack Function) functions
13- handle_bool = (Struct ("?" ).pack , lambda v : False if len (v ) == 0 else Struct ("?" ).unpack (v )[0 ])
14- handle_ulong = (Struct ("L" ).pack , lambda v : Struct ("L" ).unpack (v )[0 ])
15- handle_str = (lambda s : s .encode ("utf-8" ), lambda b : b .decode ("utf-8" ))
16- handle_date = (
17+ _bool_struct = Struct ("?" )
18+ _ulong_struct = Struct ("L" )
19+
20+ handle_bool : Handler = (
21+ _bool_struct .pack ,
22+ lambda v : False if len (v ) == 0 else _bool_struct .unpack (v )[0 ],
23+ )
24+ handle_ulong : Handler = (_ulong_struct .pack , lambda v : _ulong_struct .unpack (v )[0 ])
25+ handle_str : Handler = (lambda s : s .encode ("utf-8" ), lambda b : b .decode ("utf-8" ))
26+ handle_date : Handler = (
1727 lambda s : s .strftime ("%Y%m%d" ).encode ("ascii" ),
1828 lambda s : datetime .strptime (s .decode ("ascii" ), "%Y%m%d" ).date (),
1929)
20- handle_bytes = (bytes , bytes )
30+ handle_bytes : Handler = (bytes , bytes )
2131# The PKCS#11 biginteger type is an array of bytes in network byte order.
2232# If you have an int type, wrap it in biginteger()
23- handle_biginteger = handle_bytes
33+ handle_biginteger : Handler = handle_bytes
2434
2535
26- def _enum (type_ ) :
36+ def _enum (type_ : type [ IntEnum ]) -> Handler :
2737 """Factory to pack/unpack ints into IntEnums."""
2838 pack , unpack = handle_ulong
2939
3040 return (lambda v : pack (int (v )), lambda v : type_ (unpack (v )))
3141
3242
33- ATTRIBUTE_TYPES = {
43+ ATTRIBUTE_TYPES : dict [ Attribute , Handler ] = {
3444 Attribute .ALWAYS_AUTHENTICATE : handle_bool ,
3545 Attribute .ALWAYS_SENSITIVE : handle_bool ,
3646 Attribute .APPLICATION : handle_str ,
@@ -96,7 +106,7 @@ def _enum(type_):
96106Map of attributes to (serialize, deserialize) functions.
97107"""
98108
99- ALL_CAPABILITIES = (
109+ ALL_CAPABILITIES : Final [ tuple [ Attribute , ...]] = (
100110 Attribute .ENCRYPT ,
101111 Attribute .DECRYPT ,
102112 Attribute .WRAP ,
@@ -107,20 +117,29 @@ def _enum(type_):
107117)
108118
109119
110- def _apply_common (template , id_ , label , store ):
120+ def _apply_common (
121+ template : dict [Attribute , Any ],
122+ id_ : bytes | None ,
123+ label : str | None ,
124+ store : bool ,
125+ ) -> None :
111126 if id_ :
112127 template [Attribute .ID ] = id_
113128 if label :
114129 template [Attribute .LABEL ] = label
115130 template [Attribute .TOKEN ] = bool (store )
116131
117132
118- def _apply_capabilities (template , possible_capas , capabilities ):
133+ def _apply_capabilities (
134+ template : dict [Attribute , Any ],
135+ possible_capas : tuple [Attribute , ...],
136+ capabilities : MechanismFlag | int ,
137+ ) -> None :
119138 for attr in possible_capas :
120139 template [attr ] = _capa_attr_to_mechanism_flag [attr ] & capabilities
121140
122141
123- _capa_attr_to_mechanism_flag = {
142+ _capa_attr_to_mechanism_flag : Final [ dict [ Attribute , MechanismFlag ]] = {
124143 Attribute .ENCRYPT : MechanismFlag .ENCRYPT ,
125144 Attribute .DECRYPT : MechanismFlag .DECRYPT ,
126145 Attribute .WRAP : MechanismFlag .WRAP ,
@@ -136,7 +155,12 @@ class AttributeMapper:
136155 Class mapping PKCS#11 attributes to and from Python values.
137156 """
138157
139- def __init__ (self ):
158+ attribute_types : dict [Attribute , Handler ]
159+ default_secret_key_template : dict [Attribute , Any ]
160+ default_public_key_template : dict [Attribute , Any ]
161+ default_private_key_template : dict [Attribute , Any ]
162+
163+ def __init__ (self ) -> None :
140164 self .attribute_types = dict (ATTRIBUTE_TYPES )
141165 self .default_secret_key_template = {
142166 Attribute .CLASS : ObjectClass .SECRET_KEY ,
@@ -158,33 +182,33 @@ def __init__(self):
158182 Attribute .SENSITIVE : True ,
159183 }
160184
161- def register_handler (self , key , pack , unpack ) :
185+ def register_handler (self , key : Attribute , pack : PackFunc , unpack : UnpackFunc ) -> None :
162186 self .attribute_types [key ] = (pack , unpack )
163187
164- def _handler (self , key ) :
188+ def _handler (self , key : Attribute ) -> Handler :
165189 try :
166190 return self .attribute_types [key ]
167191 except KeyError as e :
168192 raise NotImplementedError (f"Can't handle attribute type { hex (key )} ." ) from e
169193
170- def pack_attribute (self , key , value ) :
194+ def pack_attribute (self , key : Attribute , value : Any ) -> bytes :
171195 """Pack a Attribute value into a bytes array."""
172196 pack , _ = self ._handler (key )
173197 return pack (value )
174198
175- def unpack_attributes (self , key , value ) :
199+ def unpack_attributes (self , key : Attribute , value : bytes ) -> Any :
176200 """Unpack a Attribute bytes array into a Python value."""
177201 _ , unpack = self ._handler (key )
178202 return unpack (value )
179203
180204 def public_key_template (
181205 self ,
182206 * ,
183- capabilities ,
184- id_ ,
185- label ,
186- store ,
187- ):
207+ capabilities : MechanismFlag | int ,
208+ id_ : bytes | None ,
209+ label : str | None ,
210+ store : bool ,
211+ ) -> dict [ Attribute , Any ] :
188212 template = self .default_public_key_template
189213 _apply_capabilities (
190214 template , (Attribute .ENCRYPT , Attribute .WRAP , Attribute .VERIFY ), capabilities
@@ -195,11 +219,11 @@ def public_key_template(
195219 def private_key_template (
196220 self ,
197221 * ,
198- capabilities ,
199- id_ ,
200- label ,
201- store ,
202- ):
222+ capabilities : MechanismFlag | int ,
223+ id_ : bytes | None ,
224+ label : str | None ,
225+ store : bool ,
226+ ) -> dict [ Attribute , Any ] :
203227 template = self .default_private_key_template
204228 _apply_capabilities (
205229 template ,
@@ -212,11 +236,11 @@ def private_key_template(
212236 def secret_key_template (
213237 self ,
214238 * ,
215- capabilities ,
216- id_ ,
217- label ,
218- store ,
219- ):
239+ capabilities : MechanismFlag | int ,
240+ id_ : bytes | None ,
241+ label : str | None ,
242+ store : bool ,
243+ ) -> dict [ Attribute , Any ] :
220244 return self .generic_key_template (
221245 self .default_secret_key_template ,
222246 capabilities = capabilities ,
@@ -227,13 +251,13 @@ def secret_key_template(
227251
228252 def generic_key_template (
229253 self ,
230- base_template ,
254+ base_template : dict [ Attribute , Any ] ,
231255 * ,
232- capabilities ,
233- id_ ,
234- label ,
235- store ,
236- ):
256+ capabilities : MechanismFlag | int ,
257+ id_ : bytes | None ,
258+ label : str | None ,
259+ store : bool ,
260+ ) -> dict [ Attribute , Any ] :
237261 template = dict (base_template )
238262 _apply_capabilities (template , ALL_CAPABILITIES , capabilities )
239263 _apply_common (template , id_ , label , store )
0 commit comments