Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions pkcs11/_pkcs11.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,40 @@ cdef class Session(HasFuncList, types.Session):
op.ingest_chunks(data)
return op.finish()

def set_pin(self, old_pin, new_pin):
cdef CK_ULONG old_pin_length
cdef CK_ULONG new_pin_length
cdef CK_OBJECT_HANDLE handle = self.handle
cdef CK_UTF8CHAR *old_pin_data
cdef CK_UTF8CHAR *new_pin_data
cdef CK_RV retval

pin_old = old_pin.encode('utf-8')
pin_new = new_pin.encode('utf-8')

old_pin_data = pin_old
new_pin_data = pin_new
old_pin_length = len(pin_old)
new_pin_length = len(pin_new)

with nogil:
retval = self.funclist.C_SetPIN(handle, old_pin_data, old_pin_length, new_pin_data, new_pin_length)
assertRV(retval)

def init_pin(self, pin):
cdef CK_OBJECT_HANDLE handle = self.handle
cdef CK_UTF8CHAR *pin_data
cdef CK_ULONG pin_length
cdef CK_RV retval

pin = pin.encode('utf-8')

pin_data = pin
pin_length = len(pin)

with nogil:
retval = self.funclist.C_InitPIN(handle, pin_data, pin_length)
assertRV(retval)

cdef class ObjectHandleWrapper(HasFuncList):
"""
Expand Down
13 changes: 13 additions & 0 deletions pkcs11/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,19 @@ def digest(self, data, **kwargs):

return self._digest_generator(data, **kwargs)

def set_pin(self, old_pin, new_pin):
"""Change the user pin."""
raise NotImplementedError()

def init_pin(self, pin):
"""
Initializes the user PIN.

Differs from set_pin in that it sets the user PIN for the first time.
Once set, the pin can be changed using set_pin.
"""
raise NotImplementedError()

def _digest(self, data, mechanism=None, mechanism_param=None):
raise NotImplementedError()

Expand Down
50 changes: 50 additions & 0 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
PKCS11Error,
)
from pkcs11.attributes import AttributeMapper, handle_bool, handle_str
from pkcs11.exceptions import PinIncorrect, PinLenRange

from . import TOKEN_PIN, TOKEN_SO_PIN, Not, Only, TestCase, requires

Expand Down Expand Up @@ -291,3 +292,52 @@ def _handler(self, key):
bool_read = key[Attribute.ID]
self.assertIsInstance(bool_read, bool)
self.assertFalse(bool_read, False)

@Only.softhsm2
def test_set_pin(self):
old_token_pin = TOKEN_PIN
new_token_pin = f"{TOKEN_PIN}56"

with self.token.open(rw=True, user_pin=old_token_pin) as session:
session.set_pin(old_token_pin, new_token_pin)

with self.token.open(user_pin=new_token_pin) as session:
self.assertIsInstance(session, pkcs11.Session)

with self.token.open(rw=True, user_pin=new_token_pin) as session:
session.set_pin(new_token_pin, old_token_pin)

with self.token.open(user_pin=old_token_pin) as session:
self.assertIsInstance(session, pkcs11.Session)

with self.token.open(rw=True, user_pin=old_token_pin) as session:
with self.assertRaises(AttributeError):
session.set_pin(None, new_token_pin)
with self.assertRaises(AttributeError):
session.set_pin(old_token_pin, None)
with self.assertRaises(PinLenRange):
session.set_pin(old_token_pin, "")
with self.assertRaises(PinIncorrect):
session.set_pin("", new_token_pin)

@Only.softhsm2
def test_init_pin(self):
new_token_pin = f"{TOKEN_PIN}56"

with self.token.open(rw=True, so_pin=TOKEN_SO_PIN) as session:
session.init_pin(new_token_pin)

with self.token.open(rw=True, user_pin=new_token_pin) as session:
self.assertIsInstance(session, pkcs11.Session)

with self.token.open(rw=True, so_pin=TOKEN_SO_PIN) as session:
session.init_pin(TOKEN_PIN)

with self.token.open(rw=True, user_pin=TOKEN_PIN) as session:
self.assertIsInstance(session, pkcs11.Session)

with self.token.open(rw=True, so_pin=TOKEN_SO_PIN) as session:
with self.assertRaises(AttributeError):
session.init_pin(None)
with self.assertRaises(PinLenRange):
session.init_pin("")
Loading