Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
greghudson committed Mar 2, 2024
1 parent 34ca9d1 commit 5173760
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get update -qq
sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh yasm
sudo apt-get install -y bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev libsasl2-dev libssl-dev python3-kdcproxy python3-pip slapd tcsh yasm softhsm2 opensc
pip3 install pyrad
- name: Build
env:
Expand Down
82 changes: 44 additions & 38 deletions src/tests/t_pkinit.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from k5test import *
import re

# Skip this test if pkinit wasn't built.
if not pkinit_enabled:
skip_rest('PKINIT tests', 'PKINIT module not built')

soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')

# Construct a krb5.conf fragment configuring pkinit.
user_pem = os.path.join(pkinit_certs, 'user.pem')
privkey_pem = os.path.join(pkinit_certs, 'privkey.pem')
Expand Down Expand Up @@ -55,9 +54,6 @@
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
p12_generic_identity = 'PKCS12:%s' % generic_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
p11_identity = 'PKCS11:' + soft_pkcs11
p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
':slotid=1:token=SoftToken (token)')

# Start a realm with the test kdb module for the following UPN SAN tests.
realm = K5Realm(kdc_conf=alias_kdc_conf, create_kdb=False, pkinit=True)
Expand Down Expand Up @@ -389,53 +385,63 @@
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
expected_code=1, expected_msg='Preauthentication failed while')

softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
realm.env['SOFTPKCS11RC'] = softpkcs11rc
softhsm2 = '/usr/lib/softhsm/libsofthsm2.so'
if not os.path.exists(softhsm2):
skip_rest('PKCS11 tests', 'SoftHSMv2 required')
pkcs11_tool = which('pkcs11-tool')
if not pkcs11_tool:
skip_rest('PKCS11 tests', 'pkcs11-tool from OpenSC required')
tool_cmd = [pkcs11_tool, '--module', softhsm2]

# Prepare a SoftHSM token.
softhsm2_conf = os.path.join(realm.testdir, 'softhsm2.conf')
softhsm2_tokens = os.path.join(realm.testdir, 'tokens')
os.mkdir(softhsm2_tokens)
realm.env['SOFTHSM2_CONF'] = softhsm2_conf
with open(softhsm2_conf, 'w') as f:
f.write('directories.tokendir = %s\n' % softhsm2_tokens)
realm.run(tool_cmd + ['--init-token', '--label', 'user',
'--so-pin', 'sopin', '--init-pin', '--pin', 'userpin'])
realm.run(tool_cmd + ['-w', user_pem, '-y', 'cert'])
realm.run(tool_cmd + ['-w', privkey_pem, '-y', 'privkey',
'-l', '--pin', 'userpin'])

# Extract the slot ID generated by SoftHSM.
out = realm.run(tool_cmd + ['-L'])
m = re.search(r'slot ID 0x([0-9a-f]+)\n', out)
if not m:
fail('could not extract slot ID from SoftHSM token')
slot_id = int(m.group(1), 16)

p11_attr = 'X509_user_identity=PKCS11:' + softhsm2
p11_token_identity = ('PKCS11:module_name=%s:slotid=%d:token=user' %
(softhsm2, slot_id))

# PKINIT with PKCS11: identity, with no need for a PIN.
mark('PKCS11 identity, no PIN')
conf = open(softpkcs11rc, 'w')
conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
conf.close()
# Expect to succeed without having to supply any more information.
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p11_identity])
mark('PKCS11 identity, with PIN (prompter)')
realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin')
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])

# PKINIT with PKCS11: identity, with a PIN supplied by the prompter.
mark('PKCS11 identity, with PIN (prompter)')
os.remove(softpkcs11rc)
conf = open(softpkcs11rc, 'w')
conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
privkey_enc_pem))
conf.close()
# Expect failure if the responder does nothing, and there's no prompter
mark('PKCS11 identity, unavailable PIN')
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
'-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ],
expected_code=2)
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p11_identity],
password='encrypted')
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
'-X', p11_attr, realm.user_princ], expected_code=2)

# Supply the wrong PIN.
mark('PKCS11 identity, wrong PIN')
expected_trace = ('PKINIT client has no configured identity; giving up',)
realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p11_identity],
flags=['-X', p11_attr],
password='wrong', expected_code=1, expected_trace=expected_trace)

# PKINIT with PKCS11: identity, with a PIN supplied by the responder.
# Supply the response in raw form.
# Supply the response in raw form. Expect the PIN_COUNT_LOW flag (1)
# to be set due to the previous test.
mark('PKCS11 identity, with PIN (responder)')
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
'-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity,
'-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
realm.run(['./responder', '-x', 'pkinit={"%s": 1}' % p11_token_identity,
'-r', 'pkinit={"%s": "userpin"}' % p11_token_identity,
'-X', p11_attr, realm.user_princ])
# Supply the response through the convenience API.
realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity,
'-p', '%s=%s' % (p11_token_identity, 'encrypted'),
realm.run(['./responder', '-X', p11_attr,
'-p', '%s=%s' % (p11_token_identity, 'userpin'),
realm.user_princ])
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
Expand Down

0 comments on commit 5173760

Please sign in to comment.