summaryrefslogtreecommitdiffstats
path: root/src/plugins/preauth/pkinit/pkinit_clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/preauth/pkinit/pkinit_clnt.c')
-rw-r--r--src/plugins/preauth/pkinit/pkinit_clnt.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index cf95bd57b2..85b0167378 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -57,6 +57,23 @@
*/
int longhorn = 0; /* Talking to a Longhorn server? */
+/**
+ * Return true if we should use ContentInfo rather than SignedData. This
+ * happens if we are talking to what might be an old (pre-6112) MIT KDC and
+ * we're using anonymous.
+ */
+static int
+use_content_info(krb5_context context, pkinit_req_context req,
+ krb5_principal client)
+{
+ if (req->rfc6112_kdc)
+ return 0;
+ if (krb5_principal_compare_any_realm(context, client,
+ krb5_anonymous_principal()))
+ return 1;
+ return 0;
+ }
+
static krb5_error_code
pkinit_as_req_create(krb5_context context, pkinit_context plgctx,
pkinit_req_context reqctx, krb5_timestamp ctsec,
@@ -347,9 +364,7 @@ pkinit_as_req_create(krb5_context context,
retval = ENOMEM;
goto cleanup;
}
- /* For the new protocol, we support anonymous. */
- if (krb5_principal_compare_any_realm(context, client,
- krb5_anonymous_principal())) {
+ if (use_content_info(context, reqctx, client))
retval = cms_contentinfo_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
CMS_SIGN_CLIENT, (unsigned char *)
@@ -357,7 +372,7 @@ pkinit_as_req_create(krb5_context context,
coded_auth_pack->length,
&req->signedAuthPack.data,
&req->signedAuthPack.length);
- } else {
+ else {
retval = cms_signeddata_create(context, plgctx->cryptoctx,
reqctx->cryptoctx, reqctx->idctx,
CMS_SIGN_CLIENT, 1,
@@ -1012,7 +1027,10 @@ pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
return EINVAL;
switch ((int) in_padata->pa_type) {
- case KRB5_PADATA_PK_AS_REQ:
+ case KRB5_PADATA_PKINIT_KX:
+ reqctx->rfc6112_kdc = 1;
+ return 0;
+ case KRB5_PADATA_PK_AS_REQ:
pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
processing_request = 1;
break;
@@ -1176,14 +1194,23 @@ cleanup:
static int
pkinit_client_get_flags(krb5_context kcontext, krb5_preauthtype patype)
{
+ if (patype == KRB5_PADATA_PKINIT_KX)
+ return PA_INFO|PA_PSEUDO;
return PA_REAL;
}
+/*
+ * We want to be notified about KRB5_PADATA_PKINIT_KX in addition to the actual
+ * pkinit patypes because RFC 6112 requires anonymous KDCs to send it. We use
+ * that to determine whether to use the broken MIT 1.9 behavior of sending
+ * ContentInfo rather than SignedData or the RFC 6112 behavior
+ */
static krb5_preauthtype supported_client_pa_types[] = {
KRB5_PADATA_PK_AS_REP,
KRB5_PADATA_PK_AS_REQ,
KRB5_PADATA_PK_AS_REP_OLD,
KRB5_PADATA_PK_AS_REQ_OLD,
+ KRB5_PADATA_PKINIT_KX,
0
};