krb5 commit: Don't ask empty responder questions in PKINIT

Greg Hudson ghudson at MIT.EDU
Mon Jul 22 12:25:49 EDT 2013


https://github.com/krb5/krb5/commit/b37a0be87e5146d730b89abd1378a3043d5015b2
commit b37a0be87e5146d730b89abd1378a3043d5015b2
Author: Nalin Dahyabhai <nalin at dahyabhai.net>
Date:   Fri Jul 19 11:33:20 2013 -0400

    Don't ask empty responder questions in PKINIT
    
    When putting together the set of identity prompts for a responder
    challenge, if we don't need a PIN or password of some kind, don't ask
    an empty question.
    
    [ghudson at mit.edu: squashed commits, modified commit message, merged
    PKCS11 test with current Python script]

 src/plugins/preauth/pkinit/pkinit_clnt.c |    7 +++++++
 src/tests/responder.c                    |    8 ++++----
 src/tests/t_pkinit.py                    |   28 +++++++++++++++++++++++-----
 3 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index f708856..9d7d7bd 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -1126,6 +1126,13 @@ pkinit_client_prep_questions(krb5_context context,
         continue;
     n = i;
 
+    /* Make sure we don't just return an empty challenge. */
+    if (n == 0) {
+        pkiDebug("%s: no questions to ask\n", __FUNCTION__);
+        retval = 0;
+        goto cleanup;
+    }
+
     /* Create the top-level object. */
     retval = k5_json_object_create(&jval);
     if (retval != 0)
diff --git a/src/tests/responder.c b/src/tests/responder.c
index 57106ff..13623d8 100644
--- a/src/tests/responder.c
+++ b/src/tests/responder.c
@@ -100,11 +100,11 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx)
             *value++ = '\0';
         /* Read the challenge. */
         challenge = krb5_responder_get_challenge(ctx, rctx, key);
-        if (challenge == NULL)
-            challenge = "";
-        /* See if the expected challenge looks like JSON-encoded data. */
         err = k5_json_decode(value, &decoded1);
-        if (err != 0) {
+        /* Check for "no challenge". */
+        if (challenge == NULL && *value == '\0') {
+            fprintf(stderr, "OK: (no challenge) == (no challenge)\n");
+        } else if (err != 0) {
             /* It's not JSON, so assume we're just after a string compare. */
             if (strcmp(challenge, value) == 0) {
                 fprintf(stderr, "OK: \"%s\" == \"%s\"\n", challenge, value);
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index fd1db92..7b20fa3 100644
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -89,7 +89,7 @@ realm.run_kadminl('delprinc -force WELLKNOWN/ANONYMOUS')
 # Run the basic test - PKINIT with FILE: identity, with no password on the key.
 realm.run(['./responder',
            '-x',
-           'pkinit={}',
+           'pkinit=',
            '-X',
            'X509_user_identity=%s' % file_identity,
            'user@%s' % realm.realm])
@@ -144,7 +144,7 @@ shutil.copy(user_pem, os.path.join(path, 'user.crt'))
 shutil.copy(user_pem, os.path.join(path_enc, 'user.crt'))
 realm.run(['./responder',
            '-x',
-           'pkinit={}',
+           'pkinit=',
            '-X',
            'X509_user_identity=%s' % dir_identity,
            'user@%s' % realm.realm])
@@ -195,7 +195,7 @@ realm.run([kvno, realm.host_princ])
 # PKINIT with PKCS12: identity, with no password on the bundle.
 realm.run(['./responder',
            '-x',
-           'pkinit={}',
+           'pkinit=',
            '-X',
            'X509_user_identity=%s' % p12_identity,
            'user@%s' % realm.realm])
@@ -243,13 +243,31 @@ realm.run([kvno, realm.host_princ])
 
 if have_soft_pkcs11:
     softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
+    realm.env['SOFTPKCS11RC'] = softpkcs11rc
+
+    # PKINIT with PKCS11: identity, with no need for a PIN.
     conf = open(softpkcs11rc, 'w')
     conf.write("%s\t%s\t%s\t%s\n" % ('user', 'user token', user_pem,
-                                     privkey_enc_pem))
+                                     privkey_pem))
     conf.close()
-    realm.env['SOFTPKCS11RC'] = softpkcs11rc
+    # Expect to succeed without having to supply any more information.
+    realm.run(['./responder',
+               '-x',
+               'pkinit=',
+               '-X',
+               'X509_user_identity=%s' % p11_identity,
+               'user@%s' % realm.realm])
+    realm.kinit('user@%s' % realm.realm,
+                flags=['-X', 'X509_user_identity=%s' % p11_identity])
+    realm.klist('user@%s' % realm.realm)
+    realm.run([kvno, realm.host_princ])
 
     # PKINIT with PKCS11: identity, with a PIN supplied by the 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
     realm.run(['./responder',
                '-x',


More information about the cvs-krb5 mailing list