Blame src/tests/t_pkinit.py

Packit fd8b60
from k5test import *
Packit fd8b60
Packit fd8b60
# Skip this test if pkinit wasn't built.
Packit fd8b60
if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
Packit fd8b60
    skip_rest('PKINIT tests', 'PKINIT module not built')
Packit fd8b60
Packit fd8b60
soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
Packit fd8b60
Packit fd8b60
# Construct a krb5.conf fragment configuring pkinit.
Packit fd8b60
certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
Packit fd8b60
ca_pem = os.path.join(certs, 'ca.pem')
Packit fd8b60
kdc_pem = os.path.join(certs, 'kdc.pem')
Packit fd8b60
user_pem = os.path.join(certs, 'user.pem')
Packit fd8b60
privkey_pem = os.path.join(certs, 'privkey.pem')
Packit fd8b60
privkey_enc_pem = os.path.join(certs, 'privkey-enc.pem')
Packit fd8b60
user_p12 = os.path.join(certs, 'user.p12')
Packit fd8b60
user_enc_p12 = os.path.join(certs, 'user-enc.p12')
Packit fd8b60
user_upn_p12 = os.path.join(certs, 'user-upn.p12')
Packit fd8b60
user_upn2_p12 = os.path.join(certs, 'user-upn2.p12')
Packit fd8b60
user_upn3_p12 = os.path.join(certs, 'user-upn3.p12')
Packit fd8b60
generic_p12 = os.path.join(certs, 'generic.p12')
Packit fd8b60
path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs')
Packit fd8b60
path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc')
Packit fd8b60
Packit fd8b60
pkinit_krb5_conf = {'realms': {'$realm': {
Packit fd8b60
            'pkinit_anchors': 'FILE:%s' % ca_pem}}}
Packit fd8b60
pkinit_kdc_conf = {'realms': {'$realm': {
Packit fd8b60
            'default_principal_flags': '+preauth',
Packit fd8b60
            'pkinit_eku_checking': 'none',
Packit fd8b60
            'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem),
Packit fd8b60
            'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}}
Packit fd8b60
restrictive_kdc_conf = {'realms': {'$realm': {
Packit fd8b60
            'restrict_anonymous_to_tgt': 'true' }}}
Packit fd8b60
freshness_kdc_conf = {'realms': {'$realm': {
Packit fd8b60
            'pkinit_require_freshness': 'true'}}}
Packit fd8b60
Packit fd8b60
testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
Packit fd8b60
              'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
Packit fd8b60
              'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}}
Packit fd8b60
alias_kdc_conf = {'realms': {'$realm': {
Packit fd8b60
            'default_principal_flags': '+preauth',
Packit fd8b60
            'pkinit_eku_checking': 'none',
Packit fd8b60
            'pkinit_allow_upn': 'true',
Packit fd8b60
            'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem),
Packit fd8b60
            'database_module': 'test'}},
Packit fd8b60
                  'dbmodules': {'test': {
Packit fd8b60
                      'db_library': 'test',
Packit fd8b60
                      'alias': {'user@krbtest.com': 'user'},
Packit fd8b60
                      'princs': testprincs}}}
Packit fd8b60
Packit fd8b60
file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem)
Packit fd8b60
file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem)
Packit fd8b60
dir_identity = 'DIR:%s' % path
Packit fd8b60
dir_enc_identity = 'DIR:%s' % path_enc
Packit fd8b60
dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'),
Packit fd8b60
                                    os.path.join(path, 'user.key'))
Packit fd8b60
dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'),
Packit fd8b60
                                        os.path.join(path_enc, 'user.key'))
Packit fd8b60
p12_identity = 'PKCS12:%s' % user_p12
Packit fd8b60
p12_upn_identity = 'PKCS12:%s' % user_upn_p12
Packit fd8b60
p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
Packit fd8b60
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
Packit fd8b60
p12_generic_identity = 'PKCS12:%s' % generic_p12
Packit fd8b60
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
Packit fd8b60
p11_identity = 'PKCS11:' + soft_pkcs11
Packit fd8b60
p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
Packit fd8b60
                      ':slotid=1:token=SoftToken (token)')
Packit fd8b60
Packit fd8b60
# Start a realm with the test kdb module for the following UPN SAN tests.
Packit fd8b60
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf,
Packit fd8b60
                create_kdb=False)
Packit fd8b60
realm.start_kdc()
Packit fd8b60
Packit fd8b60
mark('UPN SANs')
Packit fd8b60
Packit fd8b60
# Compatibility check: cert contains UPN "user", which matches the
Packit fd8b60
# request principal user@KRBTEST.COM if parsed as a normal principal.
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity])
Packit fd8b60
Packit fd8b60
# Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches
Packit fd8b60
# the request principal user@KRBTEST.COM if parsed as a normal principal.
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity])
Packit fd8b60
Packit fd8b60
# Cert contains UPN "user@krbtest.com" which is aliased to the request
Packit fd8b60
# principal.
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_upn_identity])
Packit fd8b60
Packit fd8b60
# Test an id-pkinit-san match to a post-canonical principal.
Packit fd8b60
realm.kinit('user@krbtest.com',
Packit fd8b60
            flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity])
Packit fd8b60
Packit fd8b60
# Test a UPN match to a post-canonical principal.  (This only works
Packit fd8b60
# for the cert with the UPN containing just "user", as we don't allow
Packit fd8b60
# UPN reparsing when comparing to the canonicalized client principal.)
Packit fd8b60
realm.kinit('user@krbtest.com',
Packit fd8b60
            flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity])
Packit fd8b60
Packit fd8b60
# Test a mismatch.
Packit fd8b60
msg = 'kinit: Client name mismatch while getting initial credentials'
Packit fd8b60
realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity, 'user2'],
Packit fd8b60
          expected_code=1, expected_msg=msg)
Packit fd8b60
realm.stop()
Packit fd8b60
Packit fd8b60
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
Packit fd8b60
                get_creds=False)
Packit fd8b60
Packit fd8b60
# Sanity check - password-based preauth should still work.
Packit fd8b60
mark('password preauth sanity check')
Packit fd8b60
realm.run(['./responder', '-r', 'password=%s' % password('user'),
Packit fd8b60
           realm.user_princ])
Packit fd8b60
realm.kinit(realm.user_princ, password=password('user'))
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# Having tested password preauth, remove the keys for better error
Packit fd8b60
# reporting.
Packit fd8b60
realm.run([kadminl, 'purgekeys', '-all', realm.user_princ])
Packit fd8b60
Packit fd8b60
# Test anonymous PKINIT.
Packit fd8b60
mark('anonymous')
Packit fd8b60
realm.kinit('@%s' % realm.realm, flags=['-n'], expected_code=1,
Packit fd8b60
            expected_msg='not found in Kerberos database')
Packit fd8b60
realm.addprinc('WELLKNOWN/ANONYMOUS')
Packit fd8b60
realm.kinit('@%s' % realm.realm, flags=['-n'])
Packit fd8b60
realm.klist('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS')
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
out = realm.run(['./adata', realm.host_princ])
Packit fd8b60
if '97:' in out:
Packit fd8b60
    fail('auth indicators seen in anonymous PKINIT ticket')
Packit fd8b60
Packit fd8b60
# Test anonymous kadmin.
Packit fd8b60
mark('anonymous kadmin')
Packit fd8b60
f = open(os.path.join(realm.testdir, 'acl'), 'a')
Packit fd8b60
f.write('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS a *')
Packit fd8b60
f.close()
Packit fd8b60
realm.start_kadmind()
Packit fd8b60
realm.run([kadmin, '-n', 'addprinc', '-pw', 'test', 'testadd'])
Packit fd8b60
realm.run([kadmin, '-n', 'getprinc', 'testadd'], expected_code=1,
Packit fd8b60
          expected_msg="Operation requires ``get'' privilege")
Packit fd8b60
realm.stop_kadmind()
Packit fd8b60
Packit fd8b60
# Test with anonymous restricted; FAST should work but kvno should fail.
Packit fd8b60
mark('anonymous restricted')
Packit fd8b60
r_env = realm.special_env('restrict', True, kdc_conf=restrictive_kdc_conf)
Packit fd8b60
realm.stop_kdc()
Packit fd8b60
realm.start_kdc(env=r_env)
Packit fd8b60
realm.kinit('@%s' % realm.realm, flags=['-n'])
Packit fd8b60
realm.kinit('@%s' % realm.realm, flags=['-n', '-T', realm.ccache])
Packit fd8b60
realm.run([kvno, realm.host_princ], expected_code=1,
Packit fd8b60
          expected_msg='KDC policy rejects request')
Packit fd8b60
Packit fd8b60
# Regression test for #8458: S4U2Self requests crash the KDC if
Packit fd8b60
# anonymous is restricted.
Packit fd8b60
mark('#8458 regression test')
Packit fd8b60
realm.kinit(realm.host_princ, flags=['-k'])
Packit fd8b60
realm.run([kvno, '-U', 'user', realm.host_princ])
Packit fd8b60
Packit fd8b60
# Go back to the normal KDC environment.
Packit fd8b60
realm.stop_kdc()
Packit fd8b60
realm.start_kdc()
Packit fd8b60
Packit fd8b60
# Run the basic test - PKINIT with FILE: identity, with no password on the key.
Packit fd8b60
mark('FILE identity, no password')
Packit fd8b60
msgs = ('Sending unauthenticated request',
Packit fd8b60
        '/Additional pre-authentication required',
Packit fd8b60
        'Preauthenticating using KDC method data',
Packit fd8b60
        'PKINIT client received freshness token from KDC',
Packit fd8b60
        'PKINIT loading CA certs and CRLs from FILE',
Packit fd8b60
        'PKINIT client making DH request',
Packit fd8b60
        ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)',
Packit fd8b60
        'PKINIT client verified DH reply',
Packit fd8b60
        'PKINIT client found id-pkinit-san in KDC cert',
Packit fd8b60
        'PKINIT client matched KDC principal krbtgt/')
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity],
Packit fd8b60
            expected_trace=msgs)
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# Try again using RSA instead of DH.
Packit fd8b60
mark('FILE identity, no password, RSA')
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity,
Packit fd8b60
                   '-X', 'flag_RSA_PROTOCOL=yes'],
Packit fd8b60
            expected_trace=('PKINIT client making RSA request',
Packit fd8b60
                            'PKINIT client verified RSA reply'))
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Test a DH parameter renegotiation by temporarily setting a 4096-bit
Packit fd8b60
# minimum on the KDC.  (Preauth type 16 is PKINIT PA_PK_AS_REQ;
Packit fd8b60
# 109 is PKINIT TD_DH_PARAMETERS; 133 is FAST PA-FX-COOKIE.)
Packit fd8b60
mark('DH parameter renegotiation')
Packit fd8b60
minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}}
Packit fd8b60
minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf)
Packit fd8b60
realm.stop_kdc()
Packit fd8b60
realm.start_kdc(env=minbits_env)
Packit fd8b60
msgs = ('Sending unauthenticated request',
Packit fd8b60
        '/Additional pre-authentication required',
Packit fd8b60
        'Preauthenticating using KDC method data',
Packit fd8b60
        'Preauth module pkinit (16) (real) returned: 0/Success',
Packit fd8b60
        ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)',
Packit fd8b60
        '/Key parameters not accepted',
Packit fd8b60
        'Preauth tryagain input types (16): 109, PA-FX-COOKIE (133)',
Packit fd8b60
        'trying again with KDC-provided parameters',
Packit fd8b60
        'Preauth module pkinit (16) tryagain returned: 0/Success',
Packit fd8b60
        ' preauth for next request: PA-PK-AS-REQ (16), PA-FX-COOKIE (133)')
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity],
Packit fd8b60
            expected_trace=msgs)
Packit fd8b60
Packit fd8b60
# Test enforcement of required freshness tokens.  (We can leave
Packit fd8b60
# freshness tokens required after this test.)
Packit fd8b60
mark('freshness token enforcement')
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity,
Packit fd8b60
                   '-X', 'disable_freshness=yes'])
Packit fd8b60
f_env = realm.special_env('freshness', True, kdc_conf=freshness_kdc_conf)
Packit fd8b60
realm.stop_kdc()
Packit fd8b60
realm.start_kdc(env=f_env)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_identity,
Packit fd8b60
                   '-X', 'disable_freshness=yes'],
Packit fd8b60
            expected_code=1, expected_msg='Preauthentication failed')
Packit fd8b60
# Anonymous should never require a freshness token.
Packit fd8b60
realm.kinit('@%s' % realm.realm, flags=['-n', '-X', 'disable_freshness=yes'])
Packit fd8b60
Packit fd8b60
# Run the basic test - PKINIT with FILE: identity, with a password on the key,
Packit fd8b60
# supplied by the prompter.
Packit fd8b60
# Expect failure if the responder does nothing, and we have no prompter.
Packit fd8b60
mark('FILE identity, password on key (prompter)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity,
Packit fd8b60
          '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ],
Packit fd8b60
          expected_code=2)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % file_enc_identity],
Packit fd8b60
            password='encrypted')
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
realm.run(['./adata', realm.host_princ],
Packit fd8b60
          expected_msg='+97: [indpkinit1, indpkinit2]')
Packit fd8b60
Packit fd8b60
# Run the basic test - PKINIT with FILE: identity, with a password on the key,
Packit fd8b60
# supplied by the responder.
Packit fd8b60
# Supply the response in raw form.
Packit fd8b60
mark('FILE identity, password on key (responder)')
Packit Service a81408
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity,
Packit Service a81408
           '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity,
Packit Service a81408
           '-X', 'X509_user_identity=%s' % file_enc_identity,
Packit Service a81408
           realm.user_princ])
Packit fd8b60
# Supply the response through the convenience API.
Packit fd8b60
realm.run(['./responder', '-X', 'X509_user_identity=%s' % file_enc_identity,
Packit fd8b60
           '-p', '%s=%s' % (file_enc_identity, 'encrypted'), realm.user_princ])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with DIR: identity, with no password on the key.
Packit fd8b60
mark('DIR identity, no password')
Packit fd8b60
os.mkdir(path)
Packit fd8b60
os.mkdir(path_enc)
Packit fd8b60
shutil.copy(privkey_pem, os.path.join(path, 'user.key'))
Packit fd8b60
shutil.copy(privkey_enc_pem, os.path.join(path_enc, 'user.key'))
Packit fd8b60
shutil.copy(user_pem, os.path.join(path, 'user.crt'))
Packit fd8b60
shutil.copy(user_pem, os.path.join(path_enc, 'user.crt'))
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % dir_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with DIR: identity, with a password on the key, supplied by the
Packit fd8b60
# prompter.
Packit fd8b60
# Expect failure if the responder does nothing, and we have no prompter.
Packit fd8b60
mark('DIR identity, password on key (prompter)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ],
Packit fd8b60
           expected_code=2)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % dir_enc_identity],
Packit fd8b60
            password='encrypted')
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with DIR: identity, with a password on the key, supplied by the
Packit fd8b60
# responder.
Packit fd8b60
# Supply the response in raw form.
Packit fd8b60
mark('DIR identity, password on key (responder)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity,
Packit fd8b60
           '-r', 'pkinit={"%s": "encrypted"}' % dir_file_enc_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ])
Packit fd8b60
# Supply the response through the convenience API.
Packit fd8b60
realm.run(['./responder', '-X', 'X509_user_identity=%s' % dir_enc_identity,
Packit fd8b60
           '-p', '%s=%s' % (dir_file_enc_identity, 'encrypted'),
Packit fd8b60
           realm.user_princ])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS12: identity, with no password on the bundle.
Packit fd8b60
mark('PKCS12 identity, no password')
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS12: identity, with a password on the bundle, supplied by the
Packit fd8b60
# prompter.
Packit fd8b60
# Expect failure if the responder does nothing, and we have no prompter.
Packit fd8b60
mark('PKCS12 identity, password on bundle (prompter)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ],
Packit fd8b60
           expected_code=2)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_enc_identity],
Packit fd8b60
            password='encrypted')
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS12: identity, with a password on the bundle, supplied by the
Packit fd8b60
# responder.
Packit fd8b60
# Supply the response in raw form.
Packit fd8b60
mark('PKCS12 identity, password on bundle (responder)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity,
Packit fd8b60
           '-r', 'pkinit={"%s": "encrypted"}' % p12_enc_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ])
Packit fd8b60
# Supply the response through the convenience API.
Packit fd8b60
realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity,
Packit fd8b60
           '-p', '%s=%s' % (p12_enc_identity, 'encrypted'),
Packit fd8b60
           realm.user_princ])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
mark('pkinit_cert_match rules')
Packit fd8b60
Packit fd8b60
# Match a single rule.
Packit fd8b60
rule = '<SAN>^user@KRBTEST.COM$'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Regression test for #8670: match a UPN SAN with a single rule.
Packit fd8b60
rule = '<SAN>^user@krbtest.com$'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_upn_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Match a combined rule (default prefix is &&).
Packit fd8b60
rule = '<SUBJECT>CN=user$<KU>digitalSignature,keyEncipherment'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Fail an && rule.
Packit fd8b60
rule = '&&<SUBJECT>O=OTHER.COM<SAN>^user@KRBTEST.COM$'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
msg = 'kinit: Certificate mismatch while getting initial credentials'
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity],
Packit fd8b60
            expected_code=1, expected_msg=msg)
Packit fd8b60
Packit fd8b60
# Pass an || rule.
Packit fd8b60
rule = '||<SUBJECT>O=KRBTEST.COM<SAN>^otheruser@KRBTEST.COM$'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Fail an || rule.
Packit fd8b60
rule = '||<SUBJECT>O=OTHER.COM<SAN>^otheruser@KRBTEST.COM$'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
msg = 'kinit: Certificate mismatch while getting initial credentials'
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_identity],
Packit fd8b60
            expected_code=1, expected_msg=msg)
Packit fd8b60
Packit fd8b60
# Authorize a client cert with no PKINIT extensions using subject and
Packit fd8b60
# issuer.  (Relies on EKU checking being turned off.)
Packit fd8b60
rule = '&&<SUBJECT>CN=user$<ISSUER>O=MIT,'
Packit fd8b60
realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p12_generic_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
Packit fd8b60
# Regression test for #8726: null deref when parsing a FILE residual
Packit fd8b60
# beginning with a comma.
Packit fd8b60
realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
Packit fd8b60
            expected_code=1, expected_msg='Preauthentication failed while')
Packit fd8b60
Packit fd8b60
softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
Packit fd8b60
realm.env['SOFTPKCS11RC'] = softpkcs11rc
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS11: identity, with no need for a PIN.
Packit fd8b60
mark('PKCS11 identity, no PIN')
Packit fd8b60
conf = open(softpkcs11rc, 'w')
Packit fd8b60
conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem, privkey_pem))
Packit fd8b60
conf.close()
Packit fd8b60
# Expect to succeed without having to supply any more information.
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p11_identity])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS11: identity, with a PIN supplied by the prompter.
Packit fd8b60
mark('PKCS11 identity, with PIN (prompter)')
Packit fd8b60
os.remove(softpkcs11rc)
Packit fd8b60
conf = open(softpkcs11rc, 'w')
Packit fd8b60
conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
Packit fd8b60
                                 privkey_enc_pem))
Packit fd8b60
conf.close()
Packit fd8b60
# Expect failure if the responder does nothing, and there's no prompter
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ],
Packit fd8b60
          expected_code=2)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p11_identity],
Packit fd8b60
            password='encrypted')
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
# Supply the wrong PIN.
Packit fd8b60
mark('PKCS11 identity, wrong PIN')
Packit fd8b60
expected_trace = ('PKINIT client has no configured identity; giving up',)
Packit fd8b60
realm.kinit(realm.user_princ,
Packit fd8b60
            flags=['-X', 'X509_user_identity=%s' % p11_identity],
Packit fd8b60
            password='wrong', expected_code=1, expected_trace=expected_trace)
Packit fd8b60
Packit fd8b60
# PKINIT with PKCS11: identity, with a PIN supplied by the responder.
Packit fd8b60
# Supply the response in raw form.
Packit fd8b60
mark('PKCS11 identity, with PIN (responder)')
Packit fd8b60
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
Packit fd8b60
           '-r', 'pkinit={"%s": "encrypted"}' % p11_token_identity,
Packit fd8b60
           '-X', 'X509_user_identity=%s' % p11_identity, realm.user_princ])
Packit fd8b60
# Supply the response through the convenience API.
Packit fd8b60
realm.run(['./responder', '-X', 'X509_user_identity=%s' % p11_identity,
Packit fd8b60
           '-p', '%s=%s' % (p11_token_identity, 'encrypted'),
Packit fd8b60
           realm.user_princ])
Packit fd8b60
realm.klist(realm.user_princ)
Packit fd8b60
realm.run([kvno, realm.host_princ])
Packit fd8b60
Packit fd8b60
success('PKINIT tests')