python-pkcs11 0.9.5__tar.gz → 0.10.0__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.
Files changed (77) hide show
  1. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/PKG-INFO +1 -1
  2. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/conf.py +0 -1
  3. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/load_module.c +2 -0
  4. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/load_module.h +2 -1
  5. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/__init__.py +0 -2
  6. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/_pkcs11.pxd +165 -0
  7. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/_pkcs11.pyi +2 -5
  8. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/_pkcs11.pyx +181 -66
  9. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/attributes.py +8 -3
  10. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/constants.py +12 -2
  11. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/defaults.py +8 -0
  12. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/mechanisms.py +21 -5
  13. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/types.py +91 -12
  14. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pyproject.toml +1 -0
  15. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/PKG-INFO +1 -1
  16. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/SOURCES.txt +1 -0
  17. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/scm_file_list.json +43 -42
  18. python_pkcs11-0.10.0/python_pkcs11.egg-info/scm_version.json +8 -0
  19. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/__init__.py +1 -1
  20. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_aes.py +8 -17
  21. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_attributes.py +0 -0
  22. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_dsa.py +1 -1
  23. python_pkcs11-0.10.0/tests/test_ml_kem.py +82 -0
  24. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_rsa.py +1 -2
  25. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_sessions.py +2 -3
  26. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_slots_and_tokens.py +1 -1
  27. python_pkcs11-0.10.0/uv.lock +1278 -0
  28. python_pkcs11-0.9.5/python_pkcs11.egg-info/scm_version.json +0 -8
  29. python_pkcs11-0.9.5/uv.lock +0 -1169
  30. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/actions/install-opencryptoki/action.yml +0 -0
  31. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/actions/install-softhsm/action.yml +0 -0
  32. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/actions/test-setup/action.yml +0 -0
  33. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/release-template.md +0 -0
  34. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/workflows/coverage.yml +0 -0
  35. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/workflows/quality.yml +0 -0
  36. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/workflows/release.yml +0 -0
  37. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.github/workflows/tests.yml +0 -0
  38. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.gitignore +0 -0
  39. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.python-version +0 -0
  40. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/.readthedocs.yaml +0 -0
  41. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/LICENSE +0 -0
  42. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/MANIFEST.in +0 -0
  43. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/README.rst +0 -0
  44. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/Makefile +0 -0
  45. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/api.rst +0 -0
  46. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/applied.rst +0 -0
  47. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/concurrency.rst +0 -0
  48. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/index.rst +0 -0
  49. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/make.bat +0 -0
  50. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/docs/opensc.rst +0 -0
  51. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/.gitignore +0 -0
  52. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/cryptoki.h +0 -0
  53. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/pkcs11.h +0 -0
  54. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/pkcs11f.h +0 -0
  55. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/extern/pkcs11t.h +0 -0
  56. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/exceptions.py +0 -0
  57. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/py.typed +0 -0
  58. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/__init__.py +0 -0
  59. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/dh.py +0 -0
  60. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/dsa.py +0 -0
  61. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/ec.py +0 -0
  62. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/rsa.py +0 -0
  63. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/pkcs11/util/x509.py +0 -0
  64. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/dependency_links.txt +0 -0
  65. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/requires.txt +0 -0
  66. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/python_pkcs11.egg-info/top_level.txt +0 -0
  67. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/setup.cfg +0 -0
  68. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_des.py +0 -0
  69. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_dh.py +0 -0
  70. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_digest.py +0 -0
  71. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_ecc.py +0 -0
  72. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_iterators.py +0 -0
  73. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_ml_dsa.py +0 -0
  74. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_multilib.py +0 -0
  75. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_public_key_external.py +0 -0
  76. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_threading.py +0 -0
  77. {python_pkcs11-0.9.5 → python_pkcs11-0.10.0}/tests/test_x509.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-pkcs11
3
- Version: 0.9.5
3
+ Version: 0.10.0
4
4
  Summary: PKCS#11 support for Python
5
5
  Author-email: Andrey Kislyuk <kislyuk@gmail.com>, Danielle Madeley <danielle@madeley.id.au>
6
6
  Maintainer-email: Andrey Kislyuk <kislyuk@gmail.com>
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  #
4
3
  # Python PKCS#11 documentation build configuration file, created by
5
4
  # sphinx-quickstart on Sat May 20 11:47:34 2017.
@@ -38,6 +38,7 @@ static P11_HANDLE* p11_open(PyObject *path_str) {
38
38
  result = (P11_HANDLE*) PyMem_Malloc(sizeof(P11_HANDLE));
39
39
  result->lib_handle = handle;
40
40
  result->get_function_list_ptr = ptr;
41
+ result->get_interface_ptr = GetProcAddress(handle, "C_GetInterface");
41
42
  }
42
43
  }
43
44
  return result;
@@ -85,6 +86,7 @@ static P11_HANDLE* p11_open(PyObject *path_str) {
85
86
  result = (P11_HANDLE*) PyMem_Malloc(sizeof(P11_HANDLE));
86
87
  result->lib_handle = handle;
87
88
  result->get_function_list_ptr = ptr;
89
+ result->get_interface_ptr = dlsym(handle, "C_GetInterface");
88
90
  }
89
91
  }
90
92
  return result;
@@ -12,7 +12,8 @@ typedef void *LIB_HANDLE;
12
12
  #ifndef P11_HANDLE
13
13
  typedef struct P11_HANDLE {
14
14
  LIB_HANDLE lib_handle;
15
- void * get_function_list_ptr;
15
+ void *get_function_list_ptr;
16
+ void *get_interface_ptr; /* C_GetInterface direct export; NULL for v2.0 libs */
16
17
  } P11_HANDLE;
17
18
  #endif
18
19
 
@@ -24,7 +24,6 @@ def lib(so: str) -> _lib_type:
24
24
  Wrap the main library call coming from Cython with a preemptive
25
25
  dynamic loading.
26
26
  """
27
- global _loaded
28
27
 
29
28
  try:
30
29
  _lib = _loaded[so]
@@ -43,7 +42,6 @@ def lib(so: str) -> _lib_type:
43
42
 
44
43
 
45
44
  def unload(so: str) -> None:
46
- global _loaded
47
45
  try:
48
46
  loaded_lib = _loaded[so]
49
47
  except KeyError:
@@ -280,6 +280,11 @@ cdef extern from '../extern/cryptoki.h':
280
280
  CK_ULONG ulContextDataLen
281
281
  CK_BYTE *pContextData
282
282
 
283
+ ctypedef struct CK_INTERFACE:
284
+ CK_UTF8CHAR *pInterfaceName
285
+ void *pFunctionList
286
+ CK_FLAGS flags
287
+
283
288
  cdef struct CK_FUNCTION_LIST:
284
289
  CK_VERSION version
285
290
  ## pointers to library functions are stored here
@@ -600,10 +605,170 @@ cdef extern from '../extern/cryptoki.h':
600
605
  CK_SLOT_ID *slot,
601
606
  void *pRserved) nogil
602
607
 
608
+
609
+ cdef struct CK_FUNCTION_LIST_3_0:
610
+ CK_RV C_GetInterfaceList(CK_INTERFACE *pInterfacesList,
611
+ CK_ULONG *pulCount) nogil
612
+
613
+ CK_RV C_GetInterface(CK_UTF8CHAR *pInterfaceName,
614
+ CK_VERSION *pVersion,
615
+ CK_INTERFACE **ppInterface,
616
+ CK_FLAGS flags) nogil
617
+
618
+ CK_RV C_LoginUser(CK_SESSION_HANDLE hSession,
619
+ CK_USER_TYPE userType,
620
+ CK_UTF8CHAR *pPin,
621
+ CK_ULONG ulPinLen,
622
+ CK_UTF8CHAR *pUsername,
623
+ CK_ULONG ulUsernameLen) nogil
624
+
625
+ CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession,
626
+ CK_FLAGS flags) nogil
627
+
628
+ CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession,
629
+ CK_MECHANISM *pMechanism,
630
+ CK_OBJECT_HANDLE hKey) nogil
631
+
632
+ CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession,
633
+ void *pParameter,
634
+ CK_ULONG ulParameterLen,
635
+ CK_BYTE *pAssociatedData,
636
+ CK_ULONG ulAssociatedDataLen,
637
+ CK_BYTE *pPlaintext,
638
+ CK_ULONG ulPlaintextLen,
639
+ CK_BYTE *pCiphertext,
640
+ CK_ULONG *pulCiphertextLen) nogil
641
+
642
+ CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession,
643
+ void *pParameter,
644
+ CK_ULONG ulParameterLen,
645
+ CK_BYTE *pAssociatedData,
646
+ CK_ULONG ulAssociatedDataLen) nogil
647
+
648
+ CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession,
649
+ void *pParameter,
650
+ CK_ULONG ulParameterLen,
651
+ CK_BYTE *pPlaintextPart,
652
+ CK_ULONG ulPlaintextPartLen,
653
+ CK_BYTE *pCiphertextPart,
654
+ CK_ULONG *pulCiphertextPartLen,
655
+ CK_FLAGS flags) nogil
656
+
657
+ CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession) nogil
658
+
659
+ CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession,
660
+ CK_MECHANISM *pMechanism,
661
+ CK_OBJECT_HANDLE hKey) nogil
662
+
663
+ CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession,
664
+ void *pParameter,
665
+ CK_ULONG ulParameterLen,
666
+ CK_BYTE *pAssociatedData,
667
+ CK_ULONG ulAssociatedDataLen,
668
+ CK_BYTE *pCiphertext,
669
+ CK_ULONG ulCiphertextLen,
670
+ CK_BYTE *pPlaintext,
671
+ CK_ULONG *pulPlaintextLen) nogil
672
+
673
+ CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession,
674
+ void *pParameter,
675
+ CK_ULONG ulParameterLen,
676
+ CK_BYTE *pAssociatedData,
677
+ CK_ULONG ulAssociatedDataLen) nogil
678
+
679
+ CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession,
680
+ void *pParameter,
681
+ CK_ULONG ulParameterLen,
682
+ CK_BYTE *pCiphertextPart,
683
+ CK_ULONG ulCiphertextPartLen,
684
+
685
+ CK_ULONG *pulPlaintextPartLen,
686
+ CK_FLAGS flags) nogil
687
+
688
+ CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession) nogil
689
+
690
+ CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession,
691
+ CK_MECHANISM *pMechanism,
692
+ CK_OBJECT_HANDLE hKey) nogil
693
+
694
+ CK_RV C_SignMessage(CK_SESSION_HANDLE hSession,
695
+ void *pParameter,
696
+ CK_ULONG ulParameterLen,
697
+ CK_BYTE *pData,
698
+ CK_ULONG ulDataLen,
699
+ CK_BYTE *pSignature,
700
+ CK_ULONG *pulSignatureLen) nogil
701
+
702
+ CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession,
703
+ void *pParameter,
704
+ CK_ULONG ulParameterLen) nogil
705
+
706
+ CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession,
707
+ void *pParameter,
708
+ CK_ULONG ulParameterLen,
709
+ CK_BYTE *pData,
710
+ CK_ULONG ulDataLen,
711
+ CK_BYTE *pSignature,
712
+ CK_ULONG *pulSignatureLen) nogil
713
+
714
+ CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession) nogil
715
+
716
+ CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession,
717
+ CK_MECHANISM *pMechanism,
718
+ CK_OBJECT_HANDLE hKey) nogil
719
+
720
+ CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession,
721
+ void *pParameter,
722
+ CK_ULONG ulParameterLen,
723
+ CK_BYTE *pData,
724
+ CK_ULONG ulDataLen,
725
+ CK_BYTE *pSignature,
726
+ CK_ULONG ulSignatureLen) nogil
727
+
728
+ CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession,
729
+ void *pParameter,
730
+ CK_ULONG ulParameterLen) nogil
731
+
732
+ CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession,
733
+ void *pParameter,
734
+ CK_ULONG ulParameterLen,
735
+ CK_BYTE *pData,
736
+ CK_ULONG ulDataLen,
737
+ CK_BYTE *pSignature,
738
+ CK_ULONG ulSignatureLen) nogil
739
+
740
+ CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession) nogil
741
+
742
+
743
+ cdef struct CK_FUNCTION_LIST_3_2:
744
+ CK_RV C_EncapsulateKey(CK_SESSION_HANDLE session,
745
+ CK_MECHANISM *mechanism,
746
+ CK_OBJECT_HANDLE public_key,
747
+ CK_ATTRIBUTE *template,
748
+ CK_ULONG count,
749
+ CK_BYTE *ciphertext,
750
+ CK_ULONG *ciphertext_len,
751
+ CK_OBJECT_HANDLE *key) nogil
752
+ CK_RV C_DecapsulateKey(CK_SESSION_HANDLE session,
753
+ CK_MECHANISM *mechanism,
754
+ CK_OBJECT_HANDLE private_key,
755
+ CK_ATTRIBUTE *template,
756
+ CK_ULONG count,
757
+ CK_BYTE *ciphertext,
758
+ CK_ULONG ciphertext_len,
759
+ CK_OBJECT_HANDLE *key) nogil
760
+
603
761
  # The only external API call that must be defined in a PKCS#11 library
604
762
  # All other APIs are taken from the CK_FUNCTION_LIST table
605
763
  ctypedef CK_RV (*C_GetFunctionList_ptr) (CK_FUNCTION_LIST **) nogil
606
764
 
765
+ ctypedef CK_RV (*C_GetInterface_ptr)(
766
+ CK_UTF8CHAR *pInterfaceName,
767
+ CK_VERSION *pVersion,
768
+ CK_INTERFACE **ppInterface,
769
+ CK_FLAGS flags
770
+ ) nogil
771
+
607
772
  ctypedef CK_RV (*KeyOperationInit) (
608
773
  CK_SESSION_HANDLE session,
609
774
  CK_MECHANISM *mechanism,
@@ -1,8 +1,7 @@
1
1
  """Type stubs for the _pkcs11 Cython extension module."""
2
2
 
3
- from __future__ import annotations
4
-
5
- from typing import Any, Iterator
3
+ from collections.abc import Iterator
4
+ from typing import Any
6
5
 
7
6
  from pkcs11.types import Slot, Token
8
7
 
@@ -34,5 +33,3 @@ class lib:
34
33
  ) -> Iterator[Token]: ...
35
34
  def get_token(self, **kwargs: Any) -> Token: ...
36
35
  def wait_for_slot_event(self, blocking: bool = True) -> Slot: ...
37
- def __str__(self) -> str: ...
38
- def __repr__(self) -> str: ...
@@ -35,9 +35,13 @@ cdef class lib(HasFuncList)
35
35
 
36
36
  cdef class HasFuncList:
37
37
  cdef CK_FUNCTION_LIST *funclist
38
+ cdef CK_FUNCTION_LIST_3_0 *funclist30
39
+ cdef CK_FUNCTION_LIST_3_2 *funclist32
38
40
 
39
41
  def __cinit__(self, *args, **kwargs):
40
42
  self.funclist = NULL
43
+ self.funclist30 = NULL
44
+ self.funclist32 = NULL
41
45
 
42
46
 
43
47
  cdef assertRV(rv) with gil:
@@ -451,6 +455,8 @@ cdef class Token(HasFuncList, types.Token):
451
455
 
452
456
  cdef Token token = Token.__new__(Token)
453
457
  token.funclist = slot.funclist
458
+ token.funclist30 = slot.funclist30
459
+ token.funclist32 = slot.funclist32
454
460
  token.slot = slot
455
461
  token.label = _CK_UTF8CHAR_to_str(label)
456
462
  token.serial = serial_number.rstrip()
@@ -847,6 +853,28 @@ def merge_templates(default_template, *user_templates):
847
853
  }
848
854
 
849
855
 
856
+ cdef _check_key_type(key_type):
857
+ if not isinstance(key_type, KeyType):
858
+ raise ArgumentsBad("`key_type` must be KeyType.")
859
+
860
+
861
+ cdef _check_bit_length(value, name, required=False):
862
+ if value is None and not required:
863
+ return
864
+ if not isinstance(value, int):
865
+ raise ArgumentsBad("`%s` is the length in bits." % name)
866
+
867
+
868
+ cdef _resolve_capabilities(key_type, capabilities):
869
+ if capabilities is not None:
870
+ return capabilities
871
+ try:
872
+ return DEFAULT_KEY_CAPABILITIES[key_type]
873
+ except KeyError:
874
+ raise ArgumentsBad("No default capabilities for this key "
875
+ "type. Please specify `capabilities`.")
876
+
877
+
850
878
  cdef class Session(HasFuncList, types.Session):
851
879
  """Extend Session with implementation."""
852
880
 
@@ -870,6 +898,8 @@ cdef class Session(HasFuncList, types.Session):
870
898
  cdef Session session = Session.__new__(Session)
871
899
 
872
900
  session.funclist = token.funclist
901
+ session.funclist30 = token.funclist30
902
+ session.funclist32 = token.funclist32
873
903
  session.token = token
874
904
 
875
905
  session.handle = handle
@@ -963,11 +993,8 @@ cdef class Session(HasFuncList, types.Session):
963
993
  def generate_domain_parameters(self, key_type, param_length, store=False,
964
994
  mechanism=None, mechanism_param=None,
965
995
  template=None):
966
- if not isinstance(key_type, KeyType):
967
- raise ArgumentsBad("`key_type` must be KeyType.")
968
-
969
- if not isinstance(param_length, int):
970
- raise ArgumentsBad("`param_length` is the length in bits.")
996
+ _check_key_type(key_type)
997
+ _check_bit_length(param_length, "param_length", required=True)
971
998
 
972
999
  mech = MechanismWithParam(
973
1000
  key_type, DEFAULT_PARAM_GENERATE_MECHANISMS,
@@ -991,18 +1018,9 @@ cdef class Session(HasFuncList, types.Session):
991
1018
  mechanism=None, mechanism_param=None,
992
1019
  template=None):
993
1020
 
994
- if not isinstance(key_type, KeyType):
995
- raise ArgumentsBad("`key_type` must be KeyType.")
996
-
997
- if key_length is not None and not isinstance(key_length, int):
998
- raise ArgumentsBad("`key_length` is the length in bits.")
999
-
1000
- if capabilities is None:
1001
- try:
1002
- capabilities = DEFAULT_KEY_CAPABILITIES[key_type]
1003
- except KeyError:
1004
- raise ArgumentsBad("No default capabilities for this key "
1005
- "type. Please specify `capabilities`.")
1021
+ _check_key_type(key_type)
1022
+ _check_bit_length(key_length, "key_length")
1023
+ capabilities = _resolve_capabilities(key_type, capabilities)
1006
1024
 
1007
1025
  mech = MechanismWithParam(
1008
1026
  key_type, DEFAULT_GENERATE_MECHANISMS,
@@ -1044,18 +1062,9 @@ cdef class Session(HasFuncList, types.Session):
1044
1062
  mechanism=None, mechanism_param=None,
1045
1063
  public_template=None, private_template=None):
1046
1064
 
1047
- if not isinstance(key_type, KeyType):
1048
- raise ArgumentsBad("`key_type` must be KeyType.")
1049
-
1050
- if key_length is not None and not isinstance(key_length, int):
1051
- raise ArgumentsBad("`key_length` is the length in bits.")
1052
-
1053
- if capabilities is None:
1054
- try:
1055
- capabilities = DEFAULT_KEY_CAPABILITIES[key_type]
1056
- except KeyError:
1057
- raise ArgumentsBad("No default capabilities for this key "
1058
- "type. Please specify `capabilities`.")
1065
+ _check_key_type(key_type)
1066
+ _check_bit_length(key_length, "key_length")
1067
+ capabilities = _resolve_capabilities(key_type, capabilities)
1059
1068
 
1060
1069
  mech = MechanismWithParam(
1061
1070
  key_type, DEFAULT_GENERATE_MECHANISMS,
@@ -1064,6 +1073,9 @@ cdef class Session(HasFuncList, types.Session):
1064
1073
  public_template_ = self.attribute_mapper.public_key_template(
1065
1074
  id_=id, label=label, store=store, capabilities=capabilities,
1066
1075
  )
1076
+ private_template_ = self.attribute_mapper.private_key_template(
1077
+ id_=id, label=label, store=store, capabilities=capabilities,
1078
+ )
1067
1079
 
1068
1080
  if key_type is KeyType.RSA:
1069
1081
  if key_length is None:
@@ -1083,11 +1095,16 @@ cdef class Session(HasFuncList, types.Session):
1083
1095
  "in `public_template` (e.g. MLDSAParameterSet.ML_DSA_65)."
1084
1096
  )
1085
1097
 
1086
- public_attrs = self.make_attribute_list(merge_templates(public_template_, public_template))
1098
+ elif key_type is KeyType.ML_KEM:
1099
+ if public_template is None or Attribute.PARAMETER_SET not in public_template:
1100
+ raise ArgumentsBad(
1101
+ "ML-KEM key generation requires `Attribute.PARAMETER_SET` "
1102
+ "in `public_template` (e.g. MLKEMParameterSet.ML_KEM_768)."
1103
+ )
1104
+ public_template_[Attribute.ENCAPSULATE] = True
1105
+ private_template_[Attribute.DECAPSULATE] = True
1087
1106
 
1088
- private_template_ = self.attribute_mapper.private_key_template(
1089
- id_=id, label=label, store=store, capabilities=capabilities,
1090
- )
1107
+ public_attrs = self.make_attribute_list(merge_templates(public_template_, public_template))
1091
1108
  private_attrs = self.make_attribute_list(merge_templates(private_template_, private_template))
1092
1109
  return self.generate_keypair_from_attrs(public_attrs, private_attrs, mech)
1093
1110
 
@@ -1362,7 +1379,7 @@ cdef object make_object(Session session, CK_OBJECT_HANDLE handle) with gil:
1362
1379
  """
1363
1380
  wrapper = ObjectHandleWrapper.wrap(session, handle)
1364
1381
 
1365
- cdef CK_ATTRIBUTE_TYPE[8] attr_keys = [
1382
+ cdef CK_ATTRIBUTE_TYPE[10] attr_keys = [
1366
1383
  Attribute.CLASS,
1367
1384
  Attribute.ENCRYPT,
1368
1385
  Attribute.DECRYPT,
@@ -1370,13 +1387,15 @@ cdef object make_object(Session session, CK_OBJECT_HANDLE handle) with gil:
1370
1387
  Attribute.VERIFY,
1371
1388
  Attribute.WRAP,
1372
1389
  Attribute.UNWRAP,
1373
- Attribute.DERIVE
1390
+ Attribute.DERIVE,
1391
+ Attribute.ENCAPSULATE,
1392
+ Attribute.DECAPSULATE,
1374
1393
  ]
1375
1394
 
1376
1395
  try:
1377
1396
  # Determine a list of base classes to manufacture our class with
1378
1397
  try:
1379
- attributes = wrapper.get_attribute_list(&attr_keys[0], 8)
1398
+ attributes = wrapper.get_attribute_list(&attr_keys[0], 10)
1380
1399
  except PKCS11Error:
1381
1400
  # retry fetching the flags one by one, some tokens do not implement error handling
1382
1401
  # on bulk fetches correctly.
@@ -1399,6 +1418,8 @@ cdef object make_object(Session session, CK_OBJECT_HANDLE handle) with gil:
1399
1418
  (Attribute.WRAP, WrapMixin),
1400
1419
  (Attribute.UNWRAP, UnwrapMixin),
1401
1420
  (Attribute.DERIVE, DeriveMixin),
1421
+ (Attribute.ENCAPSULATE, EncapsulateMixin),
1422
+ (Attribute.DECAPSULATE, DecapsulateMixin),
1402
1423
  ):
1403
1424
  try:
1404
1425
  if attributes.get(attribute, session.attribute_mapper):
@@ -1437,12 +1458,7 @@ class GenerateWithParametersMixin(types.DomainParameters):
1437
1458
  public_template=None, private_template=None):
1438
1459
 
1439
1460
  cdef Session session = self.session
1440
- if capabilities is None:
1441
- try:
1442
- capabilities = DEFAULT_KEY_CAPABILITIES[self.key_type]
1443
- except KeyError:
1444
- raise ArgumentsBad("No default capabilities for this key "
1445
- "type. Please specify `capabilities`.")
1461
+ capabilities = _resolve_capabilities(self.key_type, capabilities)
1446
1462
 
1447
1463
  mech = MechanismWithParam(self.key_type, DEFAULT_GENERATE_MECHANISMS, mechanism, mechanism_param)
1448
1464
 
@@ -1861,15 +1877,8 @@ class UnwrapMixin(types.UnwrapMixin):
1861
1877
  if not isinstance(object_class, ObjectClass):
1862
1878
  raise ArgumentsBad("`object_class` must be ObjectClass.")
1863
1879
 
1864
- if not isinstance(key_type, KeyType):
1865
- raise ArgumentsBad("`key_type` must be KeyType.")
1866
-
1867
- if capabilities is None:
1868
- try:
1869
- capabilities = DEFAULT_KEY_CAPABILITIES[key_type]
1870
- except KeyError:
1871
- raise ArgumentsBad("No default capabilities for this key "
1872
- "type. Please specify `capabilities`.")
1880
+ _check_key_type(key_type)
1881
+ capabilities = _resolve_capabilities(key_type, capabilities)
1873
1882
 
1874
1883
  mech = MechanismWithParam(self.key_type, DEFAULT_WRAP_MECHANISMS, mechanism, mechanism_param)
1875
1884
 
@@ -1912,18 +1921,9 @@ class DeriveMixin(types.DeriveMixin):
1912
1921
  mechanism=None, mechanism_param=None,
1913
1922
  template=None):
1914
1923
 
1915
- if not isinstance(key_type, KeyType):
1916
- raise ArgumentsBad("`key_type` must be KeyType.")
1917
-
1918
- if not isinstance(key_length, int):
1919
- raise ArgumentsBad("`key_length` is the length in bits.")
1920
-
1921
- if capabilities is None:
1922
- try:
1923
- capabilities = DEFAULT_KEY_CAPABILITIES[key_type]
1924
- except KeyError:
1925
- raise ArgumentsBad("No default capabilities for this key "
1926
- "type. Please specify `capabilities`.")
1924
+ _check_key_type(key_type)
1925
+ _check_bit_length(key_length, "key_length", required=True)
1926
+ capabilities = _resolve_capabilities(key_type, capabilities)
1927
1927
 
1928
1928
  mech = MechanismWithParam(self.key_type, DEFAULT_DERIVE_MECHANISMS, mechanism, mechanism_param)
1929
1929
 
@@ -1949,6 +1949,103 @@ class DeriveMixin(types.DeriveMixin):
1949
1949
  return make_object(session, key)
1950
1950
 
1951
1951
 
1952
+ class EncapsulateMixin(types.EncapsulateMixin):
1953
+ """Expand EncapsulateMixin with an implementation (ML-KEM)."""
1954
+
1955
+ def encapsulate_key(self, key_type,
1956
+ key_length=None,
1957
+ id=None, label=None,
1958
+ store=False, capabilities=None,
1959
+ mechanism=None, mechanism_param=None,
1960
+ template=None):
1961
+
1962
+ _check_key_type(key_type)
1963
+ capabilities = _resolve_capabilities(key_type, capabilities)
1964
+
1965
+ mech = MechanismWithParam(self.key_type, DEFAULT_ENCAPSULATE_MECHANISMS, mechanism, mechanism_param)
1966
+
1967
+ cdef Session session = self.session
1968
+
1969
+ if session.funclist32 == NULL:
1970
+ raise FunctionNotSupported("C_EncapsulateKey requires a PKCS#11 v3.2+ library")
1971
+
1972
+ template_ = session.attribute_mapper.secret_key_template(
1973
+ capabilities=capabilities, id_=id, label=label, store=store,
1974
+ )
1975
+ if key_length is not None:
1976
+ template_[Attribute.VALUE_LEN] = key_length // 8
1977
+ template_[Attribute.KEY_TYPE] = key_type
1978
+ cdef AttributeList attrs = session.make_attribute_list(merge_templates(template_, template))
1979
+ cdef CK_MECHANISM *mech_data = mech.data
1980
+ cdef CK_OBJECT_HANDLE pub_key = self.handle
1981
+ cdef CK_ATTRIBUTE *attr_data = attrs.data
1982
+ cdef CK_ULONG attr_count = attrs.count
1983
+ cdef CK_ULONG ct_len = 0
1984
+ cdef CK_OBJECT_HANDLE ss_handle
1985
+ cdef CK_RV retval
1986
+
1987
+ with nogil:
1988
+ retval = session.funclist32.C_EncapsulateKey(
1989
+ session.handle, mech_data, pub_key,
1990
+ attr_data, attr_count, NULL, &ct_len, &ss_handle)
1991
+ assertRV(retval)
1992
+
1993
+ cdef CK_BYTE [:] ct_buf = CK_BYTE_buffer(ct_len)
1994
+
1995
+ with nogil:
1996
+ retval = session.funclist32.C_EncapsulateKey(
1997
+ session.handle, mech_data, pub_key,
1998
+ attr_data, attr_count, &ct_buf[0], &ct_len, &ss_handle)
1999
+ assertRV(retval)
2000
+
2001
+ return (bytes(ct_buf[:ct_len]), make_object(session, ss_handle))
2002
+
2003
+
2004
+ class DecapsulateMixin(types.DecapsulateMixin):
2005
+ """Expand DecapsulateMixin with an implementation (ML-KEM)."""
2006
+
2007
+ def decapsulate_key(self, ciphertext, key_type,
2008
+ key_length=None,
2009
+ id=None, label=None,
2010
+ store=False, capabilities=None,
2011
+ mechanism=None, mechanism_param=None,
2012
+ template=None):
2013
+
2014
+ _check_key_type(key_type)
2015
+ capabilities = _resolve_capabilities(key_type, capabilities)
2016
+
2017
+ mech = MechanismWithParam(self.key_type, DEFAULT_ENCAPSULATE_MECHANISMS, mechanism, mechanism_param)
2018
+
2019
+ cdef Session session = self.session
2020
+
2021
+ if session.funclist32 == NULL:
2022
+ raise FunctionNotSupported("C_DecapsulateKey requires a PKCS#11 v3.2+ library")
2023
+
2024
+ template_ = session.attribute_mapper.secret_key_template(
2025
+ capabilities=capabilities, id_=id, label=label, store=store,
2026
+ )
2027
+ if key_length is not None:
2028
+ template_[Attribute.VALUE_LEN] = key_length // 8
2029
+ template_[Attribute.KEY_TYPE] = key_type
2030
+ cdef AttributeList attrs = session.make_attribute_list(merge_templates(template_, template))
2031
+ cdef CK_MECHANISM *mech_data = mech.data
2032
+ cdef CK_OBJECT_HANDLE priv_key = self.handle
2033
+ cdef CK_BYTE *ct_ptr = ciphertext
2034
+ cdef CK_ULONG ct_len = <CK_ULONG> len(ciphertext)
2035
+ cdef CK_ATTRIBUTE *attr_data = attrs.data
2036
+ cdef CK_ULONG attr_count = attrs.count
2037
+ cdef CK_OBJECT_HANDLE key
2038
+ cdef CK_RV retval
2039
+
2040
+ with nogil:
2041
+ retval = session.funclist32.C_DecapsulateKey(
2042
+ session.handle, mech_data, priv_key,
2043
+ attr_data, attr_count, ct_ptr, ct_len, &key)
2044
+ assertRV(retval)
2045
+
2046
+ return make_object(session, key)
2047
+
2048
+
1952
2049
  _CLASS_MAP = {
1953
2050
  ObjectClass.SECRET_KEY: SecretKey,
1954
2051
  ObjectClass.PUBLIC_KEY: PublicKey,
@@ -1960,6 +2057,7 @@ _CLASS_MAP = {
1960
2057
  cdef extern from "../extern/load_module.c":
1961
2058
  ctypedef struct P11_HANDLE:
1962
2059
  void *get_function_list_ptr
2060
+ void *get_interface_ptr
1963
2061
 
1964
2062
  object p11_error()
1965
2063
  P11_HANDLE* p11_open(object path_str)
@@ -2063,6 +2161,22 @@ cdef class lib(HasFuncList):
2063
2161
  self._cryptoki_version = info.cryptokiVersion
2064
2162
  self._library_version = info.libraryVersion
2065
2163
 
2164
+ cdef C_GetInterface_ptr get_interface
2165
+ cdef CK_INTERFACE *iface
2166
+ cdef CK_VERSION ver
2167
+ if self._p11_handle.get_interface_ptr != NULL:
2168
+ get_interface = <C_GetInterface_ptr>self._p11_handle.get_interface_ptr
2169
+ ver.major = 3
2170
+ ver.minor = 0
2171
+ retval = get_interface(<CK_UTF8CHAR*>"PKCS 11", &ver, &iface, 0)
2172
+ if retval == CKR_OK and iface != NULL:
2173
+ self.funclist30 = <CK_FUNCTION_LIST_3_0*>iface.pFunctionList
2174
+ ver.major = 3
2175
+ ver.minor = 2
2176
+ retval = get_interface(<CK_UTF8CHAR*>"PKCS 11", &ver, &iface, 0)
2177
+ if retval == CKR_OK and iface != NULL:
2178
+ self.funclist32 = <CK_FUNCTION_LIST_3_2*>iface.pFunctionList
2179
+
2066
2180
  @property
2067
2181
  def library_version(self):
2068
2182
  """Hardware version (:class:`tuple`)."""
@@ -2117,9 +2231,10 @@ cdef class lib(HasFuncList):
2117
2231
  retval = self.funclist.C_GetSlotInfo(slot_id, &info)
2118
2232
  assertRV(retval)
2119
2233
 
2120
- slots.append(
2121
- Slot.make(self.funclist, slot_id, info, self._cryptoki_version)
2122
- )
2234
+ slot = Slot.make(self.funclist, slot_id, info, self._cryptoki_version)
2235
+ slot.funclist30 = self.funclist30
2236
+ slot.funclist32 = self.funclist32
2237
+ slots.append(slot)
2123
2238
 
2124
2239
  return slots
2125
2240