More work on SAML code
[mech_eap.git] / util_context.c
index 33324de..13372ea 100644 (file)
@@ -55,28 +55,45 @@ gssEapAllocContext(OM_uint32 *minor,
 
     ctx->state = EAP_STATE_AUTHENTICATE;
 
+    /*
+     * Integrity, confidentiality, sequencing and replay detection are
+     * always available.  Regardless of what flags are requested in
+     * GSS_Init_sec_context, implementations MUST set the flag corresponding
+     * to these services in the output of GSS_Init_sec_context and
+     * GSS_Accept_sec_context.
+    */
+    ctx->gssFlags = GSS_C_TRANS_FLAG    |   /* exporting contexts */
+                    GSS_C_INTEG_FLAG    |   /* integrity */
+                    GSS_C_CONF_FLAG     |   /* confidentiality */
+                    GSS_C_SEQUENCE_FLAG |   /* sequencing */
+                    GSS_C_REPLAY_FLAG;      /* replay detection */
+
     *pCtx = ctx;
 
     return GSS_S_COMPLETE;
 }
 
 static void
-releaseInitiatorContext(struct eap_gss_initiator_ctx *ctx)
+releaseInitiatorContext(struct gss_eap_initiator_ctx *ctx)
 {
     eap_peer_sm_deinit(ctx->eap);
-    wpabuf_free(ctx->eapReqData);
 }
 
 static void
-releaseAcceptorContext(struct eap_gss_acceptor_ctx *ctx)
+releaseAcceptorContext(struct gss_eap_acceptor_ctx *ctx)
 {
+#ifdef BUILTIN_EAP
+    eap_server_sm_deinit(ctx->eap);
+    if (ctx->tlsContext != NULL)
+        tls_deinit(ctx->tlsContext);
+#endif
 }
 
 OM_uint32
 gssEapReleaseContext(OM_uint32 *minor,
                      gss_ctx_id_t *pCtx)
 {
-    OM_uint32 major, tmpMinor;
+    OM_uint32 tmpMinor;
     gss_ctx_id_t ctx = *pCtx;
     krb5_context krbContext = NULL;
 
@@ -96,7 +113,7 @@ gssEapReleaseContext(OM_uint32 *minor,
     gssEapReleaseName(&tmpMinor, &ctx->initiatorName);
     gssEapReleaseName(&tmpMinor, &ctx->acceptorName);
     gss_release_oid(&tmpMinor, &ctx->mechanismUsed);
-    sequenceFree(ctx->seqState);
+    sequenceFree(&tmpMinor, &ctx->seqState);
 
     GSSEAP_MUTEX_DESTROY(&ctx->mutex);
 
@@ -107,3 +124,71 @@ 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)
+{
+    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;
+    gss_OID_desc oidBuf;
+    gss_OID oid;
+
+    if (ctx->mechanismUsed != GSS_C_NO_OID) {
+        oid = ctx->mechanismUsed;
+    } else {
+        oidBuf.elements = NULL;
+        oidBuf.length = 0;
+        oid = &oidBuf;
+    }
+
+    major = verifyTokenHeader(minor, oid, &bodySize, &p,
+                              inputToken->length, tokenType);
+    if (GSS_ERROR(major))
+        return GSS_S_DEFECTIVE_TOKEN;
+
+    if (ctx->mechanismUsed == GSS_C_NO_OID) {
+        if (!gssEapIsConcreteMechanismOid(oid))
+            return GSS_S_BAD_MECH;
+
+        if (!gssEapInternalizeOid(oid, &ctx->mechanismUsed)) {
+            major = duplicateOid(minor, oid, &ctx->mechanismUsed);
+            if (GSS_ERROR(major))
+                return major;
+        }
+    }
+
+    innerInputToken->length = bodySize;
+    innerInputToken->value = p;
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}