Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add token and pin initialization #110

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
46 changes: 46 additions & 0 deletions pkcs11/_pkcs11.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,31 @@ class Slot(types.Slot):
class Token(types.Token):
"""Extend Token with implementation."""

def init_token(self, token_label, so_pin):
cdef CK_SLOT_ID slot_id = self.slot.slot_id
cdef CK_UTF8CHAR *pin_data
cdef CK_ULONG pin_length
cdef CK_UTF8CHAR *label

if token_label is None or so_pin is None:
raise ArgumentsBad("Set both `token_label` and `so_pin`")

pin = so_pin.encode('utf-8')
tlabel = token_label.encode('utf-8')

if pin and tlabel:
pin_data = pin
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to reassign these?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I suppose you do for nogil, NM

pin_length = len(pin)
label = tlabel

with nogil:
assertRV(_funclist.C_InitToken(slot_id, pin_data, pin_length,
label))

return True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than returning True/False out of this function, it's probably better to return None or raise ArgumentsBad. That means you can try/except/finally your codepath.


return False

def open(self, rw=False, user_pin=None, so_pin=None):
cdef CK_SLOT_ID slot_id = self.slot.slot_id
cdef CK_SESSION_HANDLE handle
Expand Down Expand Up @@ -373,6 +398,27 @@ def merge_templates(default_template, *user_templates):
class Session(types.Session):
"""Extend Session with implementation."""

def init_pin(self, user_pin):
cdef CK_OBJECT_HANDLE handle = self._handle
cdef CK_UTF8CHAR *pin_data
cdef CK_ULONG pin_length

if user_pin is None:
raise ArgumentsBad("Set `user_pin`")

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

if pin:
pin_data = pin
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to reassign this.

pin_length = len(pin)

with nogil:
assertRV(_funclist.C_InitPIN(handle, pin_data, pin_length))

return True

return False

def close(self):
cdef CK_OBJECT_HANDLE handle = self._handle

Expand Down
13 changes: 13 additions & 0 deletions tests/test_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ def test_open_session_and_login_so(self):
with self.token.open(rw=True, so_pin=TOKEN_SO_PIN) as session:
self.assertIsInstance(session, pkcs11.Session)

@Only.softhsm2 # We don't have credentials to do this for other platforms
def test_init_pin(self):
temp_token_pin = "bearsbeetsbattlestargalactica"

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

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

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

@requires(pkcs11.Mechanism.AES_KEY_GEN)
def test_generate_key(self):
with self.token.open(user_pin=TOKEN_PIN) as session:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_slots_and_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,23 @@ def test_get_token(self):
self.assertEqual(token.label, TOKEN)
self.assertIn(pkcs11.TokenFlag.TOKEN_INITIALIZED, token.flags)
self.assertIn(pkcs11.TokenFlag.LOGIN_REQUIRED, token.flags)

@Only.softhsm2
def test_init_token(self):
lib = pkcs11.lib(LIB)
tokens = lib.get_tokens()
temp_token_pin = "bearsbeetsbattlestargalactica"
temp_token_label = "schrute"

for token in tokens:
if pkcs11.TokenFlag.TOKEN_INITIALIZED not in token.flags:
self.assertTrue(token.init_token(temp_token_label,
temp_token_pin))
break
else:
raise AssertionError("No Uninitialized token found")

token, *_ = lib.get_tokens(token_label=temp_token_label)

self.assertIn(pkcs11.TokenFlag.TOKEN_INITIALIZED, token.flags)
self.assertNotIn(pkcs11.TokenFlag.USER_PIN_INITIALIZED, token.flags)