krb5 commit: Add tests for PKINIT using responder functionality
Greg Hudson
ghudson at MIT.EDU
Thu Jul 18 00:59:05 EDT 2013
https://github.com/krb5/krb5/commit/d3d07c3b2f3710c520af5698c096f124cc90f916
commit d3d07c3b2f3710c520af5698c096f124cc90f916
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date: Wed Jul 3 17:10:55 2013 -0400
Add tests for PKINIT using responder functionality
We now also test that the PKINIT challenge looks like we expect it to
look, that PKINIT fails if we don't provide a response or a prompter
callback, and that PKINIT succeeds with a response provided using either
the raw responder API or the PKINIT responder functions.
One thing that we don't check is which specific error code we get when
PKINIT fails: the OpenSSL and NSS versions return different error codes
(some mixture of EIO, ENOMEM, ENOENT, and KRB5KDC_ERR_PREAUTH_FAILED)
when they encounter trouble loading client credentials.
ticket: 7680
src/tests/t_authpkinit.py | 160 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 160 insertions(+), 0 deletions(-)
diff --git a/src/tests/t_authpkinit.py b/src/tests/t_authpkinit.py
index fdb3216..a7ca66a 100644
--- a/src/tests/t_authpkinit.py
+++ b/src/tests/t_authpkinit.py
@@ -41,9 +41,16 @@ file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem)
file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem)
dir_identity = 'DIR:%s' % path
dir_enc_identity = 'DIR:%s' % path_enc
+dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'),
+ os.path.join(path, 'user.key'))
+dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'),
+ os.path.join(path_enc, 'user.key'))
p12_identity = 'PKCS12:%s' % user_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
p11_identity = 'PKCS11:soft-pkcs11.so'
+p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:'
+ 'slotid=1:token=SoftToken (token)')
+
# Set up the DIR: identities. They go away as a side-effect of reinitializing
# the realm testdir, so we don't have a specific cleanup method.
def setup_dir_identities(realm):
@@ -57,6 +64,12 @@ def setup_dir_identities(realm):
# Run the basic test - PKINIT with FILE: identity, with no password on the key.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
+realm.run(['./responder',
+ '-x',
+ 'pkinit={}',
+ '-X',
+ 'X509_user_identity=%s' % file_identity,
+ 'user@%s' % realm.realm])
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % file_identity])
realm.klist('user@%s' % realm.realm)
@@ -67,6 +80,14 @@ realm.stop()
# supplied by the prompter.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
+# Expect failure if the responder does nothing, and we have no prompter.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % file_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % file_enc_identity,
+ 'user@%s' % realm.realm],
+ expected_code=2)
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % file_enc_identity],
password='encrypted')
@@ -74,10 +95,40 @@ realm.klist('user@%s' % realm.realm)
realm.run([kvno, realm.host_princ])
realm.stop()
+# Run the basic test - PKINIT with FILE: identity, with a password on the key,
+# supplied by the responder.
+realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
+ get_creds=False)
+# Supply the response in raw form.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % file_enc_identity,
+ '-r',
+ 'pkinit={"%s": "encrypted"}' % file_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % file_enc_identity,
+ 'user@%s' % realm.realm])
+# Supply the response through the convenience API.
+realm.run(['./responder',
+ '-X',
+ 'X509_user_identity=%s' % file_enc_identity,
+ '-p',
+ '%s=%s' % (file_enc_identity, 'encrypted'),
+ 'user@%s' % realm.realm])
+realm.klist('user@%s' % realm.realm)
+realm.run([kvno, realm.host_princ])
+realm.stop()
+
# PKINIT with DIR: identity, with no password on the key.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
setup_dir_identities(realm)
+realm.run(['./responder',
+ '-x',
+ 'pkinit={}',
+ '-X',
+ 'X509_user_identity=%s' % dir_identity,
+ 'user@%s' % realm.realm])
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % dir_identity])
realm.klist('user@%s' % realm.realm)
@@ -89,6 +140,15 @@ realm.stop()
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
setup_dir_identities(realm)
+# Expect failure if the responder does nothing, and we have no prompter.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' %
+ dir_file_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % dir_enc_identity,
+ 'user@%s' % realm.realm],
+ expected_code=2)
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % dir_enc_identity],
password='encrypted')
@@ -96,9 +156,41 @@ realm.klist('user@%s' % realm.realm)
realm.run([kvno, realm.host_princ])
realm.stop()
+# PKINIT with DIR: identity, with a password on the key, supplied by the
+# responder.
+realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
+ get_creds=False)
+setup_dir_identities(realm)
+# Supply the response in raw form.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' %
+ dir_file_enc_identity,
+ '-r',
+ 'pkinit={"%s": "encrypted"}' % dir_file_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % dir_enc_identity,
+ 'user@%s' % realm.realm])
+# Supply the response through the convenience API.
+realm.run(['./responder',
+ '-X',
+ 'X509_user_identity=%s' % dir_enc_identity,
+ '-p',
+ '%s=%s' % (dir_file_enc_identity, 'encrypted'),
+ 'user@%s' % realm.realm])
+realm.klist('user@%s' % realm.realm)
+realm.run([kvno, realm.host_princ])
+realm.stop()
+
# PKINIT with PKCS12: identity, with no password on the bundle.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
+realm.run(['./responder',
+ '-x',
+ 'pkinit={}',
+ '-X',
+ 'X509_user_identity=%s' % p12_identity,
+ 'user@%s' % realm.realm])
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % p12_identity])
realm.klist('user@%s' % realm.realm)
@@ -109,6 +201,14 @@ realm.stop()
# prompter.
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)
+# Expect failure if the responder does nothing, and we have no prompter.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % p12_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % p12_enc_identity,
+ 'user@%s' % realm.realm],
+ expected_code=2)
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % p12_enc_identity],
password='encrypted')
@@ -116,6 +216,30 @@ realm.klist('user@%s' % realm.realm)
realm.run([kvno, realm.host_princ])
realm.stop()
+# PKINIT with PKCS12: identity, with a password on the bundle, supplied by the
+# responder.
+realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
+ get_creds=False)
+# Supply the response in raw form.
+realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % p12_enc_identity,
+ '-r',
+ 'pkinit={"%s": "encrypted"}' % p12_enc_identity,
+ '-X',
+ 'X509_user_identity=%s' % p12_enc_identity,
+ 'user@%s' % realm.realm])
+# Supply the response through the convenience API.
+realm.run(['./responder',
+ '-X',
+ 'X509_user_identity=%s' % p12_enc_identity,
+ '-p',
+ '%s=%s' % (p12_enc_identity, 'encrypted'),
+ 'user@%s' % realm.realm])
+realm.klist('user@%s' % realm.realm)
+realm.run([kvno, realm.host_princ])
+realm.stop()
+
if have_soft_pkcs11:
os.environ['SOFTPKCS11RC'] = os.path.join(os.getcwd(), 'testdir',
'soft-pkcs11.rc')
@@ -127,12 +251,48 @@ if have_soft_pkcs11:
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
+ realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % p11_token_identity,
+ '-X',
+ 'X509_user_identity=%s' % p11_identity,
+ 'user@%s' % realm.realm],
+ expected_code=2)
realm.kinit('user@%s' % realm.realm,
flags=['-X', 'X509_user_identity=%s' % p11_identity],
password='encrypted')
realm.klist('user@%s' % realm.realm)
realm.run([kvno, realm.host_princ])
realm.stop()
+
+ # PKINIT with PKCS11: identity, with a PIN supplied by the responder.
+ realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
+ get_creds=False)
+ conf = open(os.environ['SOFTPKCS11RC'], 'w')
+ conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
+ privkey_enc_pem))
+ conf.close()
+ # Supply the response in raw form.
+ realm.run(['./responder',
+ '-x',
+ 'pkinit={"%s": 0}' % p11_token_identity,
+ '-r',
+ 'pkinit={"%s": "encrypted"}' %
+ p11_token_identity,
+ '-X',
+ 'X509_user_identity=%s' % p11_identity,
+ 'user@%s' % realm.realm])
+ # Supply the response through the convenience API.
+ realm.run(['./responder',
+ '-X',
+ 'X509_user_identity=%s' % p11_identity,
+ '-p',
+ '%s=%s' % (p11_token_identity, 'encrypted'),
+ 'user@%s' % realm.realm])
+ realm.klist('user@%s' % realm.realm)
+ realm.run([kvno, realm.host_princ])
+ realm.stop()
else:
output('soft-pkcs11.so not found: skipping tests with PKCS11 identities\n')
More information about the cvs-krb5
mailing list