krb5 commit: Avoid draft 9 fallback after PKINIT failure
Greg Hudson <[email protected]>
| Newsgroups | gmane.comp.encryption.kerberos.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://github.com/krb5/krb5/commit/0963fa5f0d01d81d3c4088088b94c455f033e921 commit 0963fa5f0d01d81d3c4088088b94c455f033e921 Author: Greg Hudson <[email protected]> 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,