krb5 commit: Avoid draft 9 fallback after PKINIT failure
Greg Hudson
ghudson at mit.edu
Thu Feb 9 11:18:02 EST 2017
https://github.com/krb5/krb5/commit/0963fa5f0d01d81d3c4088088b94c455f033e921
commit 0963fa5f0d01d81d3c4088088b94c455f033e921
Author: Greg Hudson <ghudson at mit.edu>
Date: Tue Feb 7 13:12:24 2017 -0500
Avoid draft 9 fallback after PKINIT failure
If a KDC offers both RFC 4556 and draft 9 PKINIT, and we experience a
client-side failure trying RFC 4556 PKINIT (e.g. due to the user
entering the wrong PKCS #11 PIN), do not try to use draft 9 PKINIT.
ticket: 8544
src/plugins/preauth/pkinit/pkinit.h | 1 +
src/plugins/preauth/pkinit/pkinit_clnt.c | 7 +++++++
src/plugins/preauth/pkinit/pkinit_trace.h | 2 ++
src/tests/t_pkinit.py | 8 ++++++++
4 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 876db94..4c488b7 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -209,6 +209,7 @@ struct _pkinit_req_context {
pkinit_identity_opts *idopts;
int do_identity_matching;
krb5_preauthtype pa_type;
+ int rfc4556_kdc;
int rfc6112_kdc;
int identity_initialized;
int identity_prompted;
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index e73ad53..f1bc6b2 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -1175,15 +1175,22 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
reqctx->rfc6112_kdc = 1;
return 0;
case KRB5_PADATA_PK_AS_REQ:
+ reqctx->rfc4556_kdc = 1;
pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
processing_request = 1;
break;
case KRB5_PADATA_PK_AS_REP:
+ reqctx->rfc4556_kdc = 1;
pkiDebug("processing KRB5_PADATA_PK_AS_REP\n");
break;
case KRB5_PADATA_PK_AS_REP_OLD:
case KRB5_PADATA_PK_AS_REQ_OLD:
+ /* Don't fall back to draft9 code if the KDC supports RFC 4556. */
+ if (reqctx->rfc4556_kdc) {
+ TRACE_PKINIT_CLIENT_NO_DRAFT9(context);
+ return KRB5KDC_ERR_PREAUTH_FAILED;
+ }
if (in_padata->length == 0) {
pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
in_padata->pa_type = KRB5_PADATA_PK_AS_REQ_OLD;
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index b3f5cbb..a3cc9cc 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -47,6 +47,8 @@
#define TRACE_PKINIT_CLIENT_KDF_OS2K(c, keyblock) \
TRACE(c, "PKINIT client used octetstring2key to compute reply key " \
"{keyblock}", keyblock)
+#define TRACE_PKINIT_CLIENT_NO_DRAFT9(c) \
+ TRACE(c, "PKINIT client ignoring draft 9 offer from RFC 4556 KDC")
#define TRACE_PKINIT_CLIENT_NO_IDENTITY(c) \
TRACE(c, "PKINIT client has no configured identity; giving up")
#define TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(c, expected, received) \
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index c8111d5..2dc057f 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -320,6 +320,14 @@ realm.kinit(realm.user_princ,
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
+# Supply the wrong PIN, and verify that we ignore the draft9 padata offer
+# in the KDC method data after RFC 4556 PKINIT fails.
+expected_trace = ('PKINIT client has no configured identity; giving up',
+ 'PKINIT client ignoring draft 9 offer from RFC 4556 KDC')
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % p11_identity],
+ 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.
realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity,
More information about the cvs-krb5
mailing list