From: Luke Howard Date: Thu, 9 Sep 2010 08:52:30 +0000 (+0200) Subject: More work on initiator state machine X-Git-Url: http://www.project-moonshot.org/gitweb/?p=cyrus-sasl.git;a=commitdiff_plain;h=01b8df341728b3eb25f579c625331c63d5063c6d More work on initiator state machine --- diff --git a/mech_eap/gssapiP_eap.h b/mech_eap/gssapiP_eap.h index f77d19a..1427272 100644 --- a/mech_eap/gssapiP_eap.h +++ b/mech_eap/gssapiP_eap.h @@ -120,17 +120,6 @@ struct eap_gss_initiator_ctx { struct eap_sm *eap; }; -typedef OM_uint32 (*eap_gss_initiator_sm)(OM_uint32 *, - gss_cred_id_t, - gss_ctx_id_t, - gss_name_t, - gss_OID, - OM_uint32, - OM_uint32, - gss_channel_bindings_t, - gss_buffer_t, - gss_buffer_t); - /* Acceptor context flags */ struct eap_gss_acceptor_ctx { }; diff --git a/mech_eap/init_sec_context.c b/mech_eap/init_sec_context.c index b52a00e..5075ed8 100644 --- a/mech_eap/init_sec_context.c +++ b/mech_eap/init_sec_context.c @@ -191,12 +191,21 @@ cleanup: return major; } -static eap_gss_initiator_sm eapGssSm[] = { - eapGssSmAuthenticate, - NULL, - NULL, - NULL, - NULL, +static struct eap_gss_initiator_sm { + enum gss_eap_token_type inputTokenType; + enum gss_eap_token_type outputTokenType; + OM_uint32 (*processToken)(OM_uint32 *, + gss_cred_id_t, + gss_ctx_id_t, + gss_name_t, + gss_OID, + OM_uint32, + OM_uint32, + gss_channel_bindings_t, + gss_buffer_t, + gss_buffer_t); +} eapGssInitiatorSm[] = { + { TOK_TYPE_EAP_REQ, TOK_TYPE_EAP_RESP, eapGssSmAuthenticate }, }; OM_uint32 @@ -216,9 +225,14 @@ gss_init_sec_context(OM_uint32 *minor, { OM_uint32 major, tmpMinor; gss_ctx_id_t ctx = *pCtx; + struct eap_gss_initiator_sm *sm = NULL; + gss_buffer_desc innerInputToken, innerOutputToken; *minor = 0; + innerOutputToken.length = 0; + innerOutputToken.value = NULL; + output_token->length = 0; output_token->value = NULL; @@ -240,23 +254,36 @@ gss_init_sec_context(OM_uint32 *minor, *pCtx = ctx; } - for (; ctx->state != EAP_STATE_ESTABLISHED; ctx->state++) { - major = (eapGssSm[ctx->state])(minor, - cred, - ctx, - target_name, - mech_type, - req_flags, - time_req, - input_chan_bindings, - input_token, - output_token); + sm = &eapGssInitiatorSm[ctx->state]; + + if (input_token != GSS_C_NO_BUFFER) { + major = gssEapVerifyToken(minor, ctx, input_token, + sm->inputTokenType, &innerInputToken); + if (GSS_ERROR(major)) + goto cleanup; + } else { + innerInputToken.length = 0; + innerInputToken.value = NULL; + } + + major = (sm->processToken)(minor, + cred, + ctx, + target_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + output_token); + if (GSS_ERROR(major)) + goto cleanup; + + if (output_token->length != 0) { + major = gssEapMakeToken(minor, ctx, &innerOutputToken, + sm->outputTokenType, output_token); if (GSS_ERROR(major)) goto cleanup; - if (output_token->length != 0) { - assert(major == GSS_S_CONTINUE_NEEDED); - break; - } } if (actual_mech_type != NULL) { @@ -274,5 +301,7 @@ cleanup: if (GSS_ERROR(major)) gssEapReleaseContext(&tmpMinor, pCtx); + gss_release_buffer(&tmpMinor, &innerOutputToken); + return major; } diff --git a/mech_eap/util.h b/mech_eap/util.h index c9fd543..5be9538 100644 --- a/mech_eap/util.h +++ b/mech_eap/util.h @@ -64,6 +64,18 @@ #define KRB_KEYTYPE(key) ((key)->enctype) +enum gss_eap_token_type { + TOK_TYPE_NONE = 0x0000, /* no token */ + TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */ + TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */ + TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */ + TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* draft-ietf-kitten-gss-naming */ + TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */ + TOK_TYPE_EAP_RESP = 0x0601, /* draft-howlett-eap-gss */ + TOK_TYPE_EAP_REQ = 0x0602, /* draft-howlett-eap-gss */ + TOK_TYPE_GSS_CHANNEL_BINDINGS = 0x0603, /* draft-howlett-eap-gss */ +}; + int gssEapSign(krb5_context context, krb5_cksumtype type, @@ -87,6 +99,20 @@ gssEapVerify(krb5_context context, OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx); OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx); +OM_uint32 +gssEapMakeToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t innerToken, + enum gss_eap_token_type tokenType, + gss_buffer_t outputToken); + +OM_uint32 +gssEapVerifyToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t inputToken, + enum gss_eap_token_type tokenType, + gss_buffer_t innerInputToken); + /* util_cred.c */ OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred); OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred); @@ -276,18 +302,6 @@ sequenceInit(void **vqueue, uint64_t seqnum, int do_replay, int do_sequence, int wide_nums); /* util_token.c */ -enum gss_eap_token_type { - TOK_TYPE_NONE = 0x0000, /* no token */ - TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */ - TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */ - TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */ - TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* draft-ietf-kitten-gss-naming */ - TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */ - TOK_TYPE_EAP_RESP = 0x0601, /* draft-howlett-eap-gss */ - TOK_TYPE_EAP_REQ = 0x0602, /* draft-howlett-eap-gss */ - TOK_TYPE_GSS_CHANNEL_BINDINGS = 0x0603, /* draft-howlett-eap-gss */ -}; - size_t tokenSize(const gss_OID_desc *mech, size_t body_size); diff --git a/mech_eap/util_context.c b/mech_eap/util_context.c index 0375108..d777b17 100644 --- a/mech_eap/util_context.c +++ b/mech_eap/util_context.c @@ -119,3 +119,51 @@ gssEapReleaseContext(OM_uint32 *minor, *minor = 0; return GSS_S_COMPLETE; } + +OM_uint32 +gssEapMakeToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t innerToken, + enum gss_eap_token_type tokenType, + gss_buffer_t outputToken) +{ + OM_uint32 major; + unsigned char *p; + + outputToken->length = tokenSize(ctx->mechanismUsed, innerToken->length); + outputToken->value = GSSEAP_MALLOC(outputToken->length); + if (outputToken->value == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + + p = (unsigned char *)outputToken->value; + makeTokenHeader(ctx->mechanismUsed, innerToken->length, &p, tokenType); + memcpy(p, innerToken->value, innerToken->length); + + *minor = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 +gssEapVerifyToken(OM_uint32 *minor, + gss_ctx_id_t ctx, + const gss_buffer_t inputToken, + enum gss_eap_token_type tokenType, + gss_buffer_t innerInputToken) +{ + OM_uint32 major; + size_t bodySize; + unsigned char *p = (unsigned char *)inputToken->value; + + major = verifyTokenHeader(ctx->mechanismUsed, &bodySize, &p, + inputToken->length, tokenType); + if (GSS_ERROR(major)) + return major; + + innerInputToken->length = bodySize; + innerInputToken->value = p; + + *minor = 0; + return GSS_S_COMPLETE; +}