python-pkcs11 0.9.2__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pkcs11/attributes.py ADDED
@@ -0,0 +1,240 @@
1
+ from datetime import datetime
2
+ from struct import Struct
3
+
4
+ from pkcs11.constants import (
5
+ Attribute,
6
+ CertificateType,
7
+ MechanismFlag,
8
+ ObjectClass,
9
+ )
10
+ from pkcs11.mechanisms import KeyType, Mechanism
11
+
12
+ # (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
+ lambda s: s.strftime("%Y%m%d").encode("ascii"),
18
+ lambda s: datetime.strptime(s.decode("ascii"), "%Y%m%d").date(),
19
+ )
20
+ handle_bytes = (bytes, bytes)
21
+ # The PKCS#11 biginteger type is an array of bytes in network byte order.
22
+ # If you have an int type, wrap it in biginteger()
23
+ handle_biginteger = handle_bytes
24
+
25
+
26
+ def _enum(type_):
27
+ """Factory to pack/unpack ints into IntEnums."""
28
+ pack, unpack = handle_ulong
29
+
30
+ return (lambda v: pack(int(v)), lambda v: type_(unpack(v)))
31
+
32
+
33
+ ATTRIBUTE_TYPES = {
34
+ Attribute.ALWAYS_AUTHENTICATE: handle_bool,
35
+ Attribute.ALWAYS_SENSITIVE: handle_bool,
36
+ Attribute.APPLICATION: handle_str,
37
+ Attribute.BASE: handle_biginteger,
38
+ Attribute.CERTIFICATE_TYPE: _enum(CertificateType),
39
+ Attribute.CHECK_VALUE: handle_bytes,
40
+ Attribute.CLASS: _enum(ObjectClass),
41
+ Attribute.COEFFICIENT: handle_biginteger,
42
+ Attribute.DECRYPT: handle_bool,
43
+ Attribute.DERIVE: handle_bool,
44
+ Attribute.EC_PARAMS: handle_bytes,
45
+ Attribute.EC_POINT: handle_bytes,
46
+ Attribute.ENCRYPT: handle_bool,
47
+ Attribute.END_DATE: handle_date,
48
+ Attribute.EXPONENT_1: handle_biginteger,
49
+ Attribute.EXPONENT_2: handle_biginteger,
50
+ Attribute.EXTRACTABLE: handle_bool,
51
+ Attribute.HASH_OF_ISSUER_PUBLIC_KEY: handle_bytes,
52
+ Attribute.HASH_OF_SUBJECT_PUBLIC_KEY: handle_bytes,
53
+ Attribute.ID: handle_bytes,
54
+ Attribute.ISSUER: handle_bytes,
55
+ Attribute.KEY_GEN_MECHANISM: _enum(Mechanism),
56
+ Attribute.KEY_TYPE: _enum(KeyType),
57
+ Attribute.LABEL: handle_str,
58
+ Attribute.LOCAL: handle_bool,
59
+ Attribute.MODIFIABLE: handle_bool,
60
+ Attribute.COPYABLE: handle_bool,
61
+ Attribute.MODULUS: handle_biginteger,
62
+ Attribute.MODULUS_BITS: handle_ulong,
63
+ Attribute.NEVER_EXTRACTABLE: handle_bool,
64
+ Attribute.OBJECT_ID: handle_bytes,
65
+ Attribute.PRIME: handle_biginteger,
66
+ Attribute.PRIME_BITS: handle_ulong,
67
+ Attribute.PRIME_1: handle_biginteger,
68
+ Attribute.PRIME_2: handle_biginteger,
69
+ Attribute.PRIVATE: handle_bool,
70
+ Attribute.PRIVATE_EXPONENT: handle_biginteger,
71
+ Attribute.PUBLIC_EXPONENT: handle_biginteger,
72
+ Attribute.SENSITIVE: handle_bool,
73
+ Attribute.SERIAL_NUMBER: handle_bytes,
74
+ Attribute.SIGN: handle_bool,
75
+ Attribute.SIGN_RECOVER: handle_bool,
76
+ Attribute.START_DATE: handle_date,
77
+ Attribute.SUBJECT: handle_bytes,
78
+ Attribute.SUBPRIME: handle_biginteger,
79
+ Attribute.SUBPRIME_BITS: handle_ulong,
80
+ Attribute.TOKEN: handle_bool,
81
+ Attribute.TRUSTED: handle_bool,
82
+ Attribute.UNIQUE_ID: handle_str,
83
+ Attribute.UNWRAP: handle_bool,
84
+ Attribute.URL: handle_str,
85
+ Attribute.VALUE: handle_biginteger,
86
+ Attribute.VALUE_BITS: handle_ulong,
87
+ Attribute.VALUE_LEN: handle_ulong,
88
+ Attribute.VERIFY: handle_bool,
89
+ Attribute.VERIFY_RECOVER: handle_bool,
90
+ Attribute.WRAP: handle_bool,
91
+ Attribute.WRAP_WITH_TRUSTED: handle_bool,
92
+ Attribute.GOSTR3410_PARAMS: handle_bytes,
93
+ Attribute.GOSTR3411_PARAMS: handle_bytes,
94
+ }
95
+ """
96
+ Map of attributes to (serialize, deserialize) functions.
97
+ """
98
+
99
+ ALL_CAPABILITIES = (
100
+ Attribute.ENCRYPT,
101
+ Attribute.DECRYPT,
102
+ Attribute.WRAP,
103
+ Attribute.UNWRAP,
104
+ Attribute.SIGN,
105
+ Attribute.VERIFY,
106
+ Attribute.DERIVE,
107
+ )
108
+
109
+
110
+ def _apply_common(template, id_, label, store):
111
+ if id_:
112
+ template[Attribute.ID] = id_
113
+ if label:
114
+ template[Attribute.LABEL] = label
115
+ template[Attribute.TOKEN] = bool(store)
116
+
117
+
118
+ def _apply_capabilities(template, possible_capas, capabilities):
119
+ for attr in possible_capas:
120
+ template[attr] = _capa_attr_to_mechanism_flag[attr] & capabilities
121
+
122
+
123
+ _capa_attr_to_mechanism_flag = {
124
+ Attribute.ENCRYPT: MechanismFlag.ENCRYPT,
125
+ Attribute.DECRYPT: MechanismFlag.DECRYPT,
126
+ Attribute.WRAP: MechanismFlag.WRAP,
127
+ Attribute.UNWRAP: MechanismFlag.UNWRAP,
128
+ Attribute.SIGN: MechanismFlag.SIGN,
129
+ Attribute.VERIFY: MechanismFlag.VERIFY,
130
+ Attribute.DERIVE: MechanismFlag.DERIVE,
131
+ }
132
+
133
+
134
+ class AttributeMapper:
135
+ """
136
+ Class mapping PKCS#11 attributes to and from Python values.
137
+ """
138
+
139
+ def __init__(self):
140
+ self.attribute_types = dict(ATTRIBUTE_TYPES)
141
+ self.default_secret_key_template = {
142
+ Attribute.CLASS: ObjectClass.SECRET_KEY,
143
+ Attribute.ID: b"",
144
+ Attribute.LABEL: "",
145
+ Attribute.PRIVATE: True,
146
+ Attribute.SENSITIVE: True,
147
+ }
148
+ self.default_public_key_template = {
149
+ Attribute.CLASS: ObjectClass.PUBLIC_KEY,
150
+ Attribute.ID: b"",
151
+ Attribute.LABEL: "",
152
+ }
153
+ self.default_private_key_template = {
154
+ Attribute.CLASS: ObjectClass.PRIVATE_KEY,
155
+ Attribute.ID: b"",
156
+ Attribute.LABEL: "",
157
+ Attribute.PRIVATE: True,
158
+ Attribute.SENSITIVE: True,
159
+ }
160
+
161
+ def register_handler(self, key, pack, unpack):
162
+ self.attribute_types[key] = (pack, unpack)
163
+
164
+ def _handler(self, key):
165
+ try:
166
+ return self.attribute_types[key]
167
+ except KeyError as e:
168
+ raise NotImplementedError(f"Can't handle attribute type {hex(key)}.") from e
169
+
170
+ def pack_attribute(self, key, value):
171
+ """Pack a Attribute value into a bytes array."""
172
+ pack, _ = self._handler(key)
173
+ return pack(value)
174
+
175
+ def unpack_attributes(self, key, value):
176
+ """Unpack a Attribute bytes array into a Python value."""
177
+ _, unpack = self._handler(key)
178
+ return unpack(value)
179
+
180
+ def public_key_template(
181
+ self,
182
+ *,
183
+ capabilities,
184
+ id_,
185
+ label,
186
+ store,
187
+ ):
188
+ template = self.default_public_key_template
189
+ _apply_capabilities(
190
+ template, (Attribute.ENCRYPT, Attribute.WRAP, Attribute.VERIFY), capabilities
191
+ )
192
+ _apply_common(template, id_, label, store)
193
+ return template
194
+
195
+ def private_key_template(
196
+ self,
197
+ *,
198
+ capabilities,
199
+ id_,
200
+ label,
201
+ store,
202
+ ):
203
+ template = self.default_private_key_template
204
+ _apply_capabilities(
205
+ template,
206
+ (Attribute.DECRYPT, Attribute.UNWRAP, Attribute.SIGN, Attribute.DERIVE),
207
+ capabilities,
208
+ )
209
+ _apply_common(template, id_, label, store)
210
+ return template
211
+
212
+ def secret_key_template(
213
+ self,
214
+ *,
215
+ capabilities,
216
+ id_,
217
+ label,
218
+ store,
219
+ ):
220
+ return self.generic_key_template(
221
+ self.default_secret_key_template,
222
+ capabilities=capabilities,
223
+ id_=id_,
224
+ label=label,
225
+ store=store,
226
+ )
227
+
228
+ def generic_key_template(
229
+ self,
230
+ base_template,
231
+ *,
232
+ capabilities,
233
+ id_,
234
+ label,
235
+ store,
236
+ ):
237
+ template = dict(base_template)
238
+ _apply_capabilities(template, ALL_CAPABILITIES, capabilities)
239
+ _apply_common(template, id_, label, store)
240
+ return template