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 ,
9+ ObjectClass )
1010from pkcs11 .mechanisms import KeyType , Mechanism
1111
12+ # Type aliases for pack/unpack function pairs
13+ PackFunc = Callable [[Any ], bytes ]
14+ UnpackFunc = Callable [[bytes ], Any ]
15+ Handler = tuple [PackFunc , UnpackFunc ]
16+
1217# (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 = (
18+ _bool_struct = Struct ("?" )
19+ _ulong_struct = Struct ("L" )
20+
21+ handle_bool : Handler = (
22+ _bool_struct .pack ,
23+ lambda v : False if len (v ) == 0 else _bool_struct .unpack (v )[0 ],
24+ )
25+ handle_ulong : Handler = (_ulong_struct .pack , lambda v : _ulong_struct .unpack (v )[0 ])
26+ handle_str : Handler = (lambda s : s .encode ("utf-8" ), lambda b : b .decode ("utf-8" ))
27+ handle_date : Handler = (
1728 lambda s : s .strftime ("%Y%m%d" ).encode ("ascii" ),
1829 lambda s : datetime .strptime (s .decode ("ascii" ), "%Y%m%d" ).date (),
1930)
20- handle_bytes = (bytes , bytes )
31+ handle_bytes : Handler = (bytes , bytes )
2132# The PKCS#11 biginteger type is an array of bytes in network byte order.
2233# If you have an int type, wrap it in biginteger()
23- handle_biginteger = handle_bytes
34+ handle_biginteger : Handler = handle_bytes
2435
2536
26- def _enum (type_ ) :
37+ def _enum (type_ : type [ IntEnum ]) -> Handler :
2738 """Factory to pack/unpack ints into IntEnums."""
2839 pack , unpack = handle_ulong
2940
3041 return (lambda v : pack (int (v )), lambda v : type_ (unpack (v )))
3142
3243
33- ATTRIBUTE_TYPES = {
44+ ATTRIBUTE_TYPES : dict [ Attribute , Handler ] = {
3445 Attribute .ALWAYS_AUTHENTICATE : handle_bool ,
3546 Attribute .ALWAYS_SENSITIVE : handle_bool ,
3647 Attribute .APPLICATION : handle_str ,
@@ -96,7 +107,7 @@ def _enum(type_):
96107Map of attributes to (serialize, deserialize) functions.
97108"""
98109
99- ALL_CAPABILITIES = (
110+ ALL_CAPABILITIES : Final [ tuple [ Attribute , ...]] = (
100111 Attribute .ENCRYPT ,
101112 Attribute .DECRYPT ,
102113 Attribute .WRAP ,
@@ -107,20 +118,29 @@ def _enum(type_):
107118)
108119
109120
110- def _apply_common (template , id_ , label , store ):
121+ def _apply_common (
122+ template : dict [Attribute , Any ],
123+ id_ : bytes | None ,
124+ label : str | None ,
125+ store : bool ,
126+ ) -> None :
111127 if id_ :
112128 template [Attribute .ID ] = id_
113129 if label :
114130 template [Attribute .LABEL ] = label
115131 template [Attribute .TOKEN ] = bool (store )
116132
117133
118- def _apply_capabilities (template , possible_capas , capabilities ):
134+ def _apply_capabilities (
135+ template : dict [Attribute , Any ],
136+ possible_capas : tuple [Attribute , ...],
137+ capabilities : MechanismFlag | int ,
138+ ) -> None :
119139 for attr in possible_capas :
120140 template [attr ] = _capa_attr_to_mechanism_flag [attr ] & capabilities
121141
122142
123- _capa_attr_to_mechanism_flag = {
143+ _capa_attr_to_mechanism_flag : Final [ dict [ Attribute , MechanismFlag ]] = {
124144 Attribute .ENCRYPT : MechanismFlag .ENCRYPT ,
125145 Attribute .DECRYPT : MechanismFlag .DECRYPT ,
126146 Attribute .WRAP : MechanismFlag .WRAP ,
@@ -136,7 +156,12 @@ class AttributeMapper:
136156 Class mapping PKCS#11 attributes to and from Python values.
137157 """
138158
139- def __init__ (self ):
159+ attribute_types : dict [Attribute , Handler ]
160+ default_secret_key_template : dict [Attribute , Any ]
161+ default_public_key_template : dict [Attribute , Any ]
162+ default_private_key_template : dict [Attribute , Any ]
163+
164+ def __init__ (self ) -> None :
140165 self .attribute_types = dict (ATTRIBUTE_TYPES )
141166 self .default_secret_key_template = {
142167 Attribute .CLASS : ObjectClass .SECRET_KEY ,
@@ -158,33 +183,33 @@ def __init__(self):
158183 Attribute .SENSITIVE : True ,
159184 }
160185
161- def register_handler (self , key , pack , unpack ) :
186+ def register_handler (self , key : Attribute , pack : PackFunc , unpack : UnpackFunc ) -> None :
162187 self .attribute_types [key ] = (pack , unpack )
163188
164- def _handler (self , key ) :
189+ def _handler (self , key : Attribute ) -> Handler :
165190 try :
166191 return self .attribute_types [key ]
167192 except KeyError as e :
168193 raise NotImplementedError (f"Can't handle attribute type { hex (key )} ." ) from e
169194
170- def pack_attribute (self , key , value ) :
195+ def pack_attribute (self , key : Attribute , value : Any ) -> bytes :
171196 """Pack a Attribute value into a bytes array."""
172197 pack , _ = self ._handler (key )
173198 return pack (value )
174199
175- def unpack_attributes (self , key , value ) :
200+ def unpack_attributes (self , key : Attribute , value : bytes ) -> Any :
176201 """Unpack a Attribute bytes array into a Python value."""
177202 _ , unpack = self ._handler (key )
178203 return unpack (value )
179204
180205 def public_key_template (
181206 self ,
182207 * ,
183- capabilities ,
184- id_ ,
185- label ,
186- store ,
187- ):
208+ capabilities : MechanismFlag | int ,
209+ id_ : bytes | None ,
210+ label : str | None ,
211+ store : bool ,
212+ ) -> dict [ Attribute , Any ] :
188213 template = self .default_public_key_template
189214 _apply_capabilities (
190215 template , (Attribute .ENCRYPT , Attribute .WRAP , Attribute .VERIFY ), capabilities
@@ -195,11 +220,11 @@ def public_key_template(
195220 def private_key_template (
196221 self ,
197222 * ,
198- capabilities ,
199- id_ ,
200- label ,
201- store ,
202- ):
223+ capabilities : MechanismFlag | int ,
224+ id_ : bytes | None ,
225+ label : str | None ,
226+ store : bool ,
227+ ) -> dict [ Attribute , Any ] :
203228 template = self .default_private_key_template
204229 _apply_capabilities (
205230 template ,
@@ -212,11 +237,11 @@ def private_key_template(
212237 def secret_key_template (
213238 self ,
214239 * ,
215- capabilities ,
216- id_ ,
217- label ,
218- store ,
219- ):
240+ capabilities : MechanismFlag | int ,
241+ id_ : bytes | None ,
242+ label : str | None ,
243+ store : bool ,
244+ ) -> dict [ Attribute , Any ] :
220245 return self .generic_key_template (
221246 self .default_secret_key_template ,
222247 capabilities = capabilities ,
@@ -227,13 +252,13 @@ def secret_key_template(
227252
228253 def generic_key_template (
229254 self ,
230- base_template ,
255+ base_template : dict [ Attribute , Any ] ,
231256 * ,
232- capabilities ,
233- id_ ,
234- label ,
235- store ,
236- ):
257+ capabilities : MechanismFlag | int ,
258+ id_ : bytes | None ,
259+ label : str | None ,
260+ store : bool ,
261+ ) -> dict [ Attribute , Any ] :
237262 template = dict (base_template )
238263 _apply_capabilities (template , ALL_CAPABILITIES , capabilities )
239264 _apply_common (template , id_ , label , store )
0 commit comments