python-pkcs11 0.9.2__tar.gz → 0.9.4__tar.gz
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.
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/actions/test-setup/action.yml +2 -2
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/workflows/coverage.yml +3 -3
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/workflows/quality.yml +10 -4
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/workflows/release.yml +6 -6
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/workflows/tests.yml +2 -2
- python_pkcs11-0.9.4/MANIFEST.in +3 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/PKG-INFO +1 -1
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/__init__.py +11 -3
- python_pkcs11-0.9.4/pkcs11/_pkcs11.pyi +38 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/_pkcs11.pyx +8 -1
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/attributes.py +70 -46
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/constants.py +7 -4
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/defaults.py +18 -14
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/exceptions.py +2 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/mechanisms.py +18 -6
- python_pkcs11-0.9.4/pkcs11/py.typed +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/types.py +301 -140
- python_pkcs11-0.9.4/pkcs11/util/__init__.py +17 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/util/dh.py +11 -4
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/util/dsa.py +13 -6
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/util/ec.py +16 -6
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/util/rsa.py +24 -14
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/util/x509.py +11 -4
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pyproject.toml +4 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/python_pkcs11.egg-info/PKG-INFO +1 -1
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/python_pkcs11.egg-info/SOURCES.txt +3 -0
- python_pkcs11-0.9.4/tests/test_attributes.py +65 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_rsa.py +89 -1
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/uv.lock +33 -2
- python_pkcs11-0.9.2/MANIFEST.in +0 -2
- python_pkcs11-0.9.2/pkcs11/util/__init__.py +0 -12
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/actions/install-opencryptoki/action.yml +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/actions/install-softhsm/action.yml +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.github/release-template.md +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.gitignore +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.python-version +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/.readthedocs.yaml +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/LICENSE +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/README.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/Makefile +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/api.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/applied.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/concurrency.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/conf.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/index.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/make.bat +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/docs/opensc.rst +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/.gitignore +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/cryptoki.h +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/load_module.c +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/load_module.h +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/pkcs11.h +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/pkcs11f.h +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/extern/pkcs11t.h +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/pkcs11/_pkcs11.pxd +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/python_pkcs11.egg-info/dependency_links.txt +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/python_pkcs11.egg-info/requires.txt +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/python_pkcs11.egg-info/top_level.txt +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/setup.cfg +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/__init__.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_aes.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_des.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_dh.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_digest.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_dsa.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_ecc.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_iterators.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_multilib.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_public_key_external.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_sessions.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_slots_and_tokens.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_threading.py +0 -0
- {python_pkcs11-0.9.2 → python_pkcs11-0.9.4}/tests/test_x509.py +0 -0
|
@@ -34,7 +34,7 @@ runs:
|
|
|
34
34
|
using: "composite"
|
|
35
35
|
steps:
|
|
36
36
|
- name: Setup Python
|
|
37
|
-
uses: actions/setup-python@
|
|
37
|
+
uses: actions/setup-python@v6
|
|
38
38
|
with:
|
|
39
39
|
python-version: ${{ inputs.python-version }}
|
|
40
40
|
- uses: ./.github/actions/install-softhsm
|
|
@@ -78,7 +78,7 @@ runs:
|
|
|
78
78
|
env:
|
|
79
79
|
PLATFORM: ${{ inputs.pkcs11-platform }}
|
|
80
80
|
- name: Install uv
|
|
81
|
-
uses: astral-sh/setup-uv@
|
|
81
|
+
uses: astral-sh/setup-uv@v7
|
|
82
82
|
with:
|
|
83
83
|
enable-cache: true
|
|
84
84
|
python-version: ${{ inputs.python-version }}
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
- opencryptoki
|
|
24
24
|
steps:
|
|
25
25
|
- name: Acquire sources
|
|
26
|
-
uses: actions/checkout@
|
|
26
|
+
uses: actions/checkout@v6
|
|
27
27
|
- name: Arm coverage-only compiler directives
|
|
28
28
|
# Unfortunately, it doesn't seem to be possible to pass directives
|
|
29
29
|
# to Cython through environment variables: https://github.com/cython/cython/issues/3930
|
|
@@ -56,7 +56,7 @@ jobs:
|
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
steps:
|
|
58
58
|
- name: Acquire sources
|
|
59
|
-
uses: actions/checkout@
|
|
59
|
+
uses: actions/checkout@v6
|
|
60
60
|
- uses: ./.github/actions/test-setup
|
|
61
61
|
id: setup
|
|
62
62
|
with:
|
|
@@ -85,7 +85,7 @@ jobs:
|
|
|
85
85
|
needs: [pytest-coverage,pytest-coverage-multilib]
|
|
86
86
|
steps:
|
|
87
87
|
# checkout necessary to ensure the uploaded report contains the correct paths
|
|
88
|
-
- uses: actions/checkout@
|
|
88
|
+
- uses: actions/checkout@v6
|
|
89
89
|
- name: Retrieve coverage reports
|
|
90
90
|
uses: actions/download-artifact@v4
|
|
91
91
|
with:
|
|
@@ -10,15 +10,15 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
12
|
- name: Acquire sources
|
|
13
|
-
uses: actions/checkout@
|
|
13
|
+
uses: actions/checkout@v6
|
|
14
14
|
|
|
15
15
|
- name: Install uv
|
|
16
|
-
uses: astral-sh/setup-uv@
|
|
16
|
+
uses: astral-sh/setup-uv@v7
|
|
17
17
|
with:
|
|
18
18
|
enable-cache: true
|
|
19
19
|
|
|
20
20
|
- name: Setup Python
|
|
21
|
-
uses: actions/setup-python@
|
|
21
|
+
uses: actions/setup-python@v6
|
|
22
22
|
with:
|
|
23
23
|
python-version: "3.13"
|
|
24
24
|
architecture: x64
|
|
@@ -30,4 +30,10 @@ jobs:
|
|
|
30
30
|
run: uv run ruff format --diff .
|
|
31
31
|
|
|
32
32
|
- name: ruff check
|
|
33
|
-
run: uv run ruff check --diff .
|
|
33
|
+
run: uv run ruff check --diff .
|
|
34
|
+
|
|
35
|
+
- name: Install project dependencies for type checking
|
|
36
|
+
run: uv pip install asn1crypto
|
|
37
|
+
|
|
38
|
+
- name: ty type check
|
|
39
|
+
run: uv run ty check pkcs11/
|
|
@@ -51,7 +51,7 @@ jobs:
|
|
|
51
51
|
echo "Tag $VERSION does not follow v<version> naming scheme"
|
|
52
52
|
exit 1
|
|
53
53
|
fi
|
|
54
|
-
- uses: actions/checkout@
|
|
54
|
+
- uses: actions/checkout@v6
|
|
55
55
|
- name: Generate release body
|
|
56
56
|
run: |
|
|
57
57
|
sed "s/:VERSION/$VERSION/g" < .github/release-template.md > release.md
|
|
@@ -75,9 +75,9 @@ jobs:
|
|
|
75
75
|
- windows-latest
|
|
76
76
|
- macos-14
|
|
77
77
|
steps:
|
|
78
|
-
- uses: actions/checkout@
|
|
78
|
+
- uses: actions/checkout@v6
|
|
79
79
|
- name: Setup Python
|
|
80
|
-
uses: actions/setup-python@
|
|
80
|
+
uses: actions/setup-python@v6
|
|
81
81
|
- name: Build wheels
|
|
82
82
|
uses: pypa/cibuildwheel@v3.3.0
|
|
83
83
|
- uses: actions/upload-artifact@v4
|
|
@@ -88,11 +88,11 @@ jobs:
|
|
|
88
88
|
runs-on: ubuntu-latest
|
|
89
89
|
needs: [extract-params]
|
|
90
90
|
steps:
|
|
91
|
-
- uses: actions/checkout@
|
|
91
|
+
- uses: actions/checkout@v6
|
|
92
92
|
- name: Setup Python
|
|
93
|
-
uses: actions/setup-python@
|
|
93
|
+
uses: actions/setup-python@v6
|
|
94
94
|
- name: Install uv
|
|
95
|
-
uses: astral-sh/setup-uv@
|
|
95
|
+
uses: astral-sh/setup-uv@v7
|
|
96
96
|
with:
|
|
97
97
|
enable-cache: true
|
|
98
98
|
- name: Build source distribution
|
|
@@ -40,7 +40,7 @@ jobs:
|
|
|
40
40
|
os: macos-14
|
|
41
41
|
steps:
|
|
42
42
|
- name: Acquire sources
|
|
43
|
-
uses: actions/checkout@
|
|
43
|
+
uses: actions/checkout@v6
|
|
44
44
|
- uses: ./.github/actions/test-setup
|
|
45
45
|
id: setup
|
|
46
46
|
with:
|
|
@@ -69,7 +69,7 @@ jobs:
|
|
|
69
69
|
- "3.14"
|
|
70
70
|
steps:
|
|
71
71
|
- name: Acquire sources
|
|
72
|
-
uses: actions/checkout@
|
|
72
|
+
uses: actions/checkout@v6
|
|
73
73
|
- uses: ./.github/actions/test-setup
|
|
74
74
|
id: setup
|
|
75
75
|
with:
|
|
@@ -2,16 +2,24 @@
|
|
|
2
2
|
:mod:`pkcs11` defines a high-level, "Pythonic" interface to PKCS#11.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
5
9
|
from pkcs11.constants import * # noqa: F403
|
|
6
10
|
from pkcs11.exceptions import * # noqa: F403
|
|
7
11
|
from pkcs11.mechanisms import * # noqa: F403
|
|
8
12
|
from pkcs11.types import * # noqa: F403
|
|
9
13
|
from pkcs11.util import dh, dsa, ec, rsa, x509 # noqa: F401
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from pkcs11._pkcs11 import lib as _lib_type
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
_loaded: dict[str, Any] = {}
|
|
12
20
|
|
|
13
21
|
|
|
14
|
-
def lib(so):
|
|
22
|
+
def lib(so: str) -> _lib_type:
|
|
15
23
|
"""
|
|
16
24
|
Wrap the main library call coming from Cython with a preemptive
|
|
17
25
|
dynamic loading.
|
|
@@ -34,7 +42,7 @@ def lib(so):
|
|
|
34
42
|
return _lib
|
|
35
43
|
|
|
36
44
|
|
|
37
|
-
def unload(so):
|
|
45
|
+
def unload(so: str) -> None:
|
|
38
46
|
global _loaded
|
|
39
47
|
try:
|
|
40
48
|
loaded_lib = _loaded[so]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Type stubs for the _pkcs11 Cython extension module."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Iterator
|
|
6
|
+
|
|
7
|
+
from pkcs11.types import Slot, Token
|
|
8
|
+
|
|
9
|
+
class lib:
|
|
10
|
+
"""Main entry point for PKCS#11 library."""
|
|
11
|
+
|
|
12
|
+
so: str
|
|
13
|
+
manufacturer_id: str
|
|
14
|
+
library_description: str
|
|
15
|
+
initialized: bool
|
|
16
|
+
|
|
17
|
+
def __init__(self, so: str) -> None: ...
|
|
18
|
+
@property
|
|
19
|
+
def library_version(self) -> tuple[int, int]: ...
|
|
20
|
+
@property
|
|
21
|
+
def cryptoki_version(self) -> tuple[int, int]: ...
|
|
22
|
+
def initialize(self) -> None: ...
|
|
23
|
+
def finalize(self) -> None: ...
|
|
24
|
+
def reinitialize(self) -> None: ...
|
|
25
|
+
def unload(self) -> None: ...
|
|
26
|
+
def get_slots(self, token_present: bool = False) -> list[Slot]: ...
|
|
27
|
+
def get_tokens(
|
|
28
|
+
self,
|
|
29
|
+
token_label: str | None = None,
|
|
30
|
+
token_serial: bytes | None = None,
|
|
31
|
+
token_flags: Any | None = None,
|
|
32
|
+
slot_flags: Any | None = None,
|
|
33
|
+
mechanisms: Any | None = None,
|
|
34
|
+
) -> Iterator[Token]: ...
|
|
35
|
+
def get_token(self, **kwargs: Any) -> Token: ...
|
|
36
|
+
def wait_for_slot_event(self, blocking: bool = True) -> Slot: ...
|
|
37
|
+
def __str__(self) -> str: ...
|
|
38
|
+
def __repr__(self) -> str: ...
|
|
@@ -1366,8 +1366,15 @@ cdef object make_object(Session session, CK_OBJECT_HANDLE handle) with gil:
|
|
|
1366
1366
|
# Determine a list of base classes to manufacture our class with
|
|
1367
1367
|
try:
|
|
1368
1368
|
attributes = wrapper.get_attribute_list(&attr_keys[0], 8)
|
|
1369
|
-
except
|
|
1369
|
+
except PKCS11Error:
|
|
1370
|
+
# retry fetching the flags one by one, some tokens do not implement error handling
|
|
1371
|
+
# on bulk fetches correctly.
|
|
1370
1372
|
attributes = {}
|
|
1373
|
+
for key in attr_keys:
|
|
1374
|
+
try:
|
|
1375
|
+
attributes[key] = wrapper[key]
|
|
1376
|
+
except (AttributeTypeInvalid, AttributeSensitive, FunctionFailed):
|
|
1377
|
+
continue
|
|
1371
1378
|
|
|
1372
1379
|
object_class = attributes.get(Attribute.CLASS, session.attribute_mapper)
|
|
1373
1380
|
bases = (_CLASS_MAP[object_class],)
|
|
@@ -1,36 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from datetime import datetime
|
|
4
|
+
from enum import IntEnum
|
|
2
5
|
from struct import Struct
|
|
6
|
+
from typing import Any, Callable, Final
|
|
3
7
|
|
|
4
|
-
from pkcs11.constants import
|
|
5
|
-
Attribute,
|
|
6
|
-
CertificateType,
|
|
7
|
-
MechanismFlag,
|
|
8
|
-
ObjectClass,
|
|
9
|
-
)
|
|
8
|
+
from pkcs11.constants import Attribute, CertificateType, MechanismFlag, ObjectClass
|
|
10
9
|
from pkcs11.mechanisms import KeyType, Mechanism
|
|
11
10
|
|
|
11
|
+
# Type aliases for pack/unpack function pairs
|
|
12
|
+
PackFunc = Callable[[Any], bytes]
|
|
13
|
+
UnpackFunc = Callable[[bytes], Any]
|
|
14
|
+
Handler = tuple[PackFunc, UnpackFunc]
|
|
15
|
+
|
|
12
16
|
# (Pack Function, Unpack Function) functions
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 = (
|
|
17
27
|
lambda s: s.strftime("%Y%m%d").encode("ascii"),
|
|
18
28
|
lambda s: datetime.strptime(s.decode("ascii"), "%Y%m%d").date(),
|
|
19
29
|
)
|
|
20
|
-
handle_bytes = (bytes, bytes)
|
|
30
|
+
handle_bytes: Handler = (bytes, bytes)
|
|
21
31
|
# The PKCS#11 biginteger type is an array of bytes in network byte order.
|
|
22
32
|
# If you have an int type, wrap it in biginteger()
|
|
23
|
-
handle_biginteger = handle_bytes
|
|
33
|
+
handle_biginteger: Handler = handle_bytes
|
|
24
34
|
|
|
25
35
|
|
|
26
|
-
def _enum(type_):
|
|
36
|
+
def _enum(type_: type[IntEnum]) -> Handler:
|
|
27
37
|
"""Factory to pack/unpack ints into IntEnums."""
|
|
28
38
|
pack, unpack = handle_ulong
|
|
29
39
|
|
|
30
40
|
return (lambda v: pack(int(v)), lambda v: type_(unpack(v)))
|
|
31
41
|
|
|
32
42
|
|
|
33
|
-
ATTRIBUTE_TYPES = {
|
|
43
|
+
ATTRIBUTE_TYPES: dict[Attribute, Handler] = {
|
|
34
44
|
Attribute.ALWAYS_AUTHENTICATE: handle_bool,
|
|
35
45
|
Attribute.ALWAYS_SENSITIVE: handle_bool,
|
|
36
46
|
Attribute.APPLICATION: handle_str,
|
|
@@ -96,7 +106,7 @@ ATTRIBUTE_TYPES = {
|
|
|
96
106
|
Map of attributes to (serialize, deserialize) functions.
|
|
97
107
|
"""
|
|
98
108
|
|
|
99
|
-
ALL_CAPABILITIES = (
|
|
109
|
+
ALL_CAPABILITIES: Final[tuple[Attribute, ...]] = (
|
|
100
110
|
Attribute.ENCRYPT,
|
|
101
111
|
Attribute.DECRYPT,
|
|
102
112
|
Attribute.WRAP,
|
|
@@ -107,7 +117,12 @@ ALL_CAPABILITIES = (
|
|
|
107
117
|
)
|
|
108
118
|
|
|
109
119
|
|
|
110
|
-
def _apply_common(
|
|
120
|
+
def _apply_common(
|
|
121
|
+
template: dict[Attribute, Any],
|
|
122
|
+
id_: bytes | None,
|
|
123
|
+
label: str | None,
|
|
124
|
+
store: bool,
|
|
125
|
+
) -> None:
|
|
111
126
|
if id_:
|
|
112
127
|
template[Attribute.ID] = id_
|
|
113
128
|
if label:
|
|
@@ -115,12 +130,16 @@ def _apply_common(template, id_, label, store):
|
|
|
115
130
|
template[Attribute.TOKEN] = bool(store)
|
|
116
131
|
|
|
117
132
|
|
|
118
|
-
def _apply_capabilities(
|
|
133
|
+
def _apply_capabilities(
|
|
134
|
+
template: dict[Attribute, Any],
|
|
135
|
+
possible_capas: tuple[Attribute, ...],
|
|
136
|
+
capabilities: MechanismFlag | int,
|
|
137
|
+
) -> None:
|
|
119
138
|
for attr in possible_capas:
|
|
120
139
|
template[attr] = _capa_attr_to_mechanism_flag[attr] & capabilities
|
|
121
140
|
|
|
122
141
|
|
|
123
|
-
_capa_attr_to_mechanism_flag = {
|
|
142
|
+
_capa_attr_to_mechanism_flag: Final[dict[Attribute, MechanismFlag]] = {
|
|
124
143
|
Attribute.ENCRYPT: MechanismFlag.ENCRYPT,
|
|
125
144
|
Attribute.DECRYPT: MechanismFlag.DECRYPT,
|
|
126
145
|
Attribute.WRAP: MechanismFlag.WRAP,
|
|
@@ -136,7 +155,12 @@ class AttributeMapper:
|
|
|
136
155
|
Class mapping PKCS#11 attributes to and from Python values.
|
|
137
156
|
"""
|
|
138
157
|
|
|
139
|
-
|
|
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:
|
|
140
164
|
self.attribute_types = dict(ATTRIBUTE_TYPES)
|
|
141
165
|
self.default_secret_key_template = {
|
|
142
166
|
Attribute.CLASS: ObjectClass.SECRET_KEY,
|
|
@@ -158,21 +182,21 @@ class AttributeMapper:
|
|
|
158
182
|
Attribute.SENSITIVE: True,
|
|
159
183
|
}
|
|
160
184
|
|
|
161
|
-
def register_handler(self, key, pack, unpack):
|
|
185
|
+
def register_handler(self, key: Attribute, pack: PackFunc, unpack: UnpackFunc) -> None:
|
|
162
186
|
self.attribute_types[key] = (pack, unpack)
|
|
163
187
|
|
|
164
|
-
def _handler(self, key):
|
|
188
|
+
def _handler(self, key: Attribute) -> Handler:
|
|
165
189
|
try:
|
|
166
190
|
return self.attribute_types[key]
|
|
167
191
|
except KeyError as e:
|
|
168
192
|
raise NotImplementedError(f"Can't handle attribute type {hex(key)}.") from e
|
|
169
193
|
|
|
170
|
-
def pack_attribute(self, key, value):
|
|
194
|
+
def pack_attribute(self, key: Attribute, value: Any) -> bytes:
|
|
171
195
|
"""Pack a Attribute value into a bytes array."""
|
|
172
196
|
pack, _ = self._handler(key)
|
|
173
197
|
return pack(value)
|
|
174
198
|
|
|
175
|
-
def unpack_attributes(self, key, value):
|
|
199
|
+
def unpack_attributes(self, key: Attribute, value: bytes) -> Any:
|
|
176
200
|
"""Unpack a Attribute bytes array into a Python value."""
|
|
177
201
|
_, unpack = self._handler(key)
|
|
178
202
|
return unpack(value)
|
|
@@ -180,12 +204,12 @@ class AttributeMapper:
|
|
|
180
204
|
def public_key_template(
|
|
181
205
|
self,
|
|
182
206
|
*,
|
|
183
|
-
capabilities,
|
|
184
|
-
id_,
|
|
185
|
-
label,
|
|
186
|
-
store,
|
|
187
|
-
):
|
|
188
|
-
template = self.default_public_key_template
|
|
207
|
+
capabilities: MechanismFlag | int,
|
|
208
|
+
id_: bytes | None,
|
|
209
|
+
label: str | None,
|
|
210
|
+
store: bool,
|
|
211
|
+
) -> dict[Attribute, Any]:
|
|
212
|
+
template = dict(self.default_public_key_template)
|
|
189
213
|
_apply_capabilities(
|
|
190
214
|
template, (Attribute.ENCRYPT, Attribute.WRAP, Attribute.VERIFY), capabilities
|
|
191
215
|
)
|
|
@@ -195,12 +219,12 @@ class AttributeMapper:
|
|
|
195
219
|
def private_key_template(
|
|
196
220
|
self,
|
|
197
221
|
*,
|
|
198
|
-
capabilities,
|
|
199
|
-
id_,
|
|
200
|
-
label,
|
|
201
|
-
store,
|
|
202
|
-
):
|
|
203
|
-
template = self.default_private_key_template
|
|
222
|
+
capabilities: MechanismFlag | int,
|
|
223
|
+
id_: bytes | None,
|
|
224
|
+
label: str | None,
|
|
225
|
+
store: bool,
|
|
226
|
+
) -> dict[Attribute, Any]:
|
|
227
|
+
template = dict(self.default_private_key_template)
|
|
204
228
|
_apply_capabilities(
|
|
205
229
|
template,
|
|
206
230
|
(Attribute.DECRYPT, Attribute.UNWRAP, Attribute.SIGN, Attribute.DERIVE),
|
|
@@ -212,11 +236,11 @@ class AttributeMapper:
|
|
|
212
236
|
def secret_key_template(
|
|
213
237
|
self,
|
|
214
238
|
*,
|
|
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]:
|
|
220
244
|
return self.generic_key_template(
|
|
221
245
|
self.default_secret_key_template,
|
|
222
246
|
capabilities=capabilities,
|
|
@@ -227,13 +251,13 @@ class AttributeMapper:
|
|
|
227
251
|
|
|
228
252
|
def generic_key_template(
|
|
229
253
|
self,
|
|
230
|
-
base_template,
|
|
254
|
+
base_template: dict[Attribute, Any],
|
|
231
255
|
*,
|
|
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]:
|
|
237
261
|
template = dict(base_template)
|
|
238
262
|
_apply_capabilities(template, ALL_CAPABILITIES, capabilities)
|
|
239
263
|
_apply_common(template, id_, label, store)
|
|
@@ -5,9 +5,12 @@ See the Python :mod:`enum` documentation for more information on how to
|
|
|
5
5
|
use these classes.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
from enum import IntEnum, IntFlag, unique
|
|
11
|
+
from typing import Final
|
|
9
12
|
|
|
10
|
-
DEFAULT = object()
|
|
13
|
+
DEFAULT: Final[object] = object()
|
|
11
14
|
"""Sentinel value used in templates.
|
|
12
15
|
|
|
13
16
|
Not all pkcs11 attribute sets are accepted by HSMs.
|
|
@@ -55,11 +58,11 @@ class ObjectClass(IntEnum):
|
|
|
55
58
|
|
|
56
59
|
_VENDOR_DEFINED = 0x80000000
|
|
57
60
|
|
|
58
|
-
def __repr__(self):
|
|
61
|
+
def __repr__(self) -> str:
|
|
59
62
|
return "<ObjectClass.%s>" % self.name
|
|
60
63
|
|
|
61
64
|
|
|
62
|
-
_ARRAY_ATTRIBUTE = 0x40000000
|
|
65
|
+
_ARRAY_ATTRIBUTE: Final[int] = 0x40000000
|
|
63
66
|
"""Attribute consists of an array of values."""
|
|
64
67
|
|
|
65
68
|
|
|
@@ -343,7 +346,7 @@ class Attribute(IntEnum):
|
|
|
343
346
|
|
|
344
347
|
_VENDOR_DEFINED = 0x80000000
|
|
345
348
|
|
|
346
|
-
def __repr__(self):
|
|
349
|
+
def __repr__(self) -> str:
|
|
347
350
|
return "<Attribute.%s>" % self.name
|
|
348
351
|
|
|
349
352
|
|
|
@@ -5,12 +5,14 @@ None of this is provided for in PKCS#11 and its correctness should not be
|
|
|
5
5
|
assumed.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Final
|
|
11
|
+
|
|
12
|
+
from pkcs11.constants import MechanismFlag
|
|
11
13
|
from pkcs11.mechanisms import MGF, KeyType, Mechanism
|
|
12
14
|
|
|
13
|
-
DEFAULT_GENERATE_MECHANISMS = {
|
|
15
|
+
DEFAULT_GENERATE_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
14
16
|
KeyType.AES: Mechanism.AES_KEY_GEN,
|
|
15
17
|
KeyType.DES2: Mechanism.DES2_KEY_GEN,
|
|
16
18
|
KeyType.DES3: Mechanism.DES3_KEY_GEN,
|
|
@@ -26,11 +28,11 @@ DEFAULT_GENERATE_MECHANISMS = {
|
|
|
26
28
|
Default mechanisms for generating keys.
|
|
27
29
|
"""
|
|
28
30
|
|
|
29
|
-
_ENCRYPTION = MechanismFlag.ENCRYPT | MechanismFlag.DECRYPT
|
|
30
|
-
_SIGNING = MechanismFlag.SIGN | MechanismFlag.VERIFY
|
|
31
|
-
_WRAPPING = MechanismFlag.WRAP | MechanismFlag.UNWRAP
|
|
31
|
+
_ENCRYPTION: Final[MechanismFlag] = MechanismFlag.ENCRYPT | MechanismFlag.DECRYPT
|
|
32
|
+
_SIGNING: Final[MechanismFlag] = MechanismFlag.SIGN | MechanismFlag.VERIFY
|
|
33
|
+
_WRAPPING: Final[MechanismFlag] = MechanismFlag.WRAP | MechanismFlag.UNWRAP
|
|
32
34
|
|
|
33
|
-
DEFAULT_KEY_CAPABILITIES = {
|
|
35
|
+
DEFAULT_KEY_CAPABILITIES: Final[dict[KeyType, MechanismFlag | int]] = {
|
|
34
36
|
KeyType.AES: _ENCRYPTION | _SIGNING | _WRAPPING,
|
|
35
37
|
KeyType.DES2: _ENCRYPTION | _SIGNING | _WRAPPING,
|
|
36
38
|
KeyType.DES3: _ENCRYPTION | _SIGNING | _WRAPPING,
|
|
@@ -45,7 +47,7 @@ DEFAULT_KEY_CAPABILITIES = {
|
|
|
45
47
|
Default capabilities for generating keys.
|
|
46
48
|
"""
|
|
47
49
|
|
|
48
|
-
DEFAULT_ENCRYPT_MECHANISMS = {
|
|
50
|
+
DEFAULT_ENCRYPT_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
49
51
|
KeyType.AES: Mechanism.AES_CBC_PAD,
|
|
50
52
|
KeyType.DES2: Mechanism.DES3_CBC_PAD,
|
|
51
53
|
KeyType.DES3: Mechanism.DES3_CBC_PAD,
|
|
@@ -55,7 +57,7 @@ DEFAULT_ENCRYPT_MECHANISMS = {
|
|
|
55
57
|
Default mechanisms for encrypt/decrypt.
|
|
56
58
|
"""
|
|
57
59
|
|
|
58
|
-
DEFAULT_SIGN_MECHANISMS = {
|
|
60
|
+
DEFAULT_SIGN_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
59
61
|
KeyType.AES: Mechanism.AES_MAC,
|
|
60
62
|
KeyType.DES2: Mechanism.DES3_MAC,
|
|
61
63
|
KeyType.DES3: Mechanism.DES3_MAC,
|
|
@@ -68,7 +70,7 @@ DEFAULT_SIGN_MECHANISMS = {
|
|
|
68
70
|
Default mechanisms for sign/verify.
|
|
69
71
|
"""
|
|
70
72
|
|
|
71
|
-
DEFAULT_WRAP_MECHANISMS = {
|
|
73
|
+
DEFAULT_WRAP_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
72
74
|
KeyType.AES: Mechanism.AES_KEY_WRAP,
|
|
73
75
|
KeyType.DES2: Mechanism.DES3_ECB,
|
|
74
76
|
KeyType.DES3: Mechanism.DES3_ECB,
|
|
@@ -78,7 +80,7 @@ DEFAULT_WRAP_MECHANISMS = {
|
|
|
78
80
|
Default mechanism for wrap/unwrap.
|
|
79
81
|
"""
|
|
80
82
|
|
|
81
|
-
DEFAULT_DERIVE_MECHANISMS = {
|
|
83
|
+
DEFAULT_DERIVE_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
82
84
|
KeyType.DH: Mechanism.DH_PKCS_DERIVE,
|
|
83
85
|
KeyType.EC: Mechanism.ECDH1_DERIVE,
|
|
84
86
|
KeyType.X9_42_DH: Mechanism.X9_42_DH_DERIVE,
|
|
@@ -87,7 +89,7 @@ DEFAULT_DERIVE_MECHANISMS = {
|
|
|
87
89
|
Default mechanisms for key derivation
|
|
88
90
|
"""
|
|
89
91
|
|
|
90
|
-
DEFAULT_PARAM_GENERATE_MECHANISMS = {
|
|
92
|
+
DEFAULT_PARAM_GENERATE_MECHANISMS: Final[dict[KeyType, Mechanism]] = {
|
|
91
93
|
KeyType.DH: Mechanism.DH_PKCS_PARAMETER_GEN,
|
|
92
94
|
KeyType.DSA: Mechanism.DSA_PARAMETER_GEN,
|
|
93
95
|
KeyType.X9_42_DH: Mechanism.X9_42_DH_PARAMETER_GEN,
|
|
@@ -97,7 +99,9 @@ Default mechanisms for domain parameter generation
|
|
|
97
99
|
"""
|
|
98
100
|
|
|
99
101
|
|
|
100
|
-
DEFAULT_MECHANISM_PARAMS
|
|
102
|
+
DEFAULT_MECHANISM_PARAMS: Final[
|
|
103
|
+
dict[Mechanism, tuple[Mechanism, MGF, None] | tuple[Mechanism, MGF, int]]
|
|
104
|
+
] = {
|
|
101
105
|
Mechanism.RSA_PKCS_OAEP: (Mechanism.SHA_1, MGF.SHA1, None),
|
|
102
106
|
Mechanism.RSA_PKCS_PSS: (Mechanism.SHA_1, MGF.SHA1, 20),
|
|
103
107
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import IntEnum
|
|
2
4
|
|
|
3
5
|
from pkcs11.exceptions import ArgumentsBad
|
|
@@ -107,7 +109,7 @@ class KeyType(IntEnum):
|
|
|
107
109
|
|
|
108
110
|
_VENDOR_DEFINED = 0x80000000
|
|
109
111
|
|
|
110
|
-
def __repr__(self):
|
|
112
|
+
def __repr__(self) -> str:
|
|
111
113
|
return "<KeyType.%s>" % self.name
|
|
112
114
|
|
|
113
115
|
|
|
@@ -751,7 +753,7 @@ class Mechanism(IntEnum):
|
|
|
751
753
|
|
|
752
754
|
_VENDOR_DEFINED = 0x80000000
|
|
753
755
|
|
|
754
|
-
def __repr__(self):
|
|
756
|
+
def __repr__(self) -> str:
|
|
755
757
|
return "<Mechanism.%s>" % self.name
|
|
756
758
|
|
|
757
759
|
|
|
@@ -775,7 +777,7 @@ class KDF(IntEnum):
|
|
|
775
777
|
SHA3_384_KDF = 0x0000000C
|
|
776
778
|
SHA3_512_KDF = 0x0000000D
|
|
777
779
|
|
|
778
|
-
def __repr__(self):
|
|
780
|
+
def __repr__(self) -> str:
|
|
779
781
|
return "<KDF.%s>" % self.name
|
|
780
782
|
|
|
781
783
|
|
|
@@ -794,12 +796,18 @@ class MGF(IntEnum):
|
|
|
794
796
|
SHA3_384 = 0x00000008
|
|
795
797
|
SHA3_512 = 0x00000009
|
|
796
798
|
|
|
797
|
-
def __repr__(self):
|
|
799
|
+
def __repr__(self) -> str:
|
|
798
800
|
return "<MGF.%s>" % self.name
|
|
799
801
|
|
|
800
802
|
|
|
801
803
|
class GCMParams:
|
|
802
|
-
|
|
804
|
+
"""Parameters for AES-GCM mode."""
|
|
805
|
+
|
|
806
|
+
nonce: bytes
|
|
807
|
+
aad: bytes | None
|
|
808
|
+
tag_bits: int
|
|
809
|
+
|
|
810
|
+
def __init__(self, nonce: bytes, aad: bytes | None = None, tag_bits: int = 128) -> None:
|
|
803
811
|
if len(nonce) > 12:
|
|
804
812
|
raise ArgumentsBad("IV must be less than 12 bytes")
|
|
805
813
|
self.nonce = nonce
|
|
@@ -808,7 +816,11 @@ class GCMParams:
|
|
|
808
816
|
|
|
809
817
|
|
|
810
818
|
class CTRParams:
|
|
811
|
-
|
|
819
|
+
"""Parameters for AES-CTR mode."""
|
|
820
|
+
|
|
821
|
+
nonce: bytes
|
|
822
|
+
|
|
823
|
+
def __init__(self, nonce: bytes) -> None:
|
|
812
824
|
if len(nonce) >= 16:
|
|
813
825
|
raise ArgumentsBad(
|
|
814
826
|
f"{nonce.hex()} is too long to serve as a CTR nonce, must be 15 bytes or less "
|
|
File without changes
|