|
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')
|