X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=mech_eap%2Finit_sec_context.c;h=37bd3d056ca1486f4581e93938c456517ba8002c;hp=9c62f5a65194e845ce565aca2f0098390280027f;hb=f3746d009c6d7f50025af1f58a85e5fee9680be6;hpb=244f18d04aaf29e68495b5ffeb40ef5cca50942f diff --git a/mech_eap/init_sec_context.c b/mech_eap/init_sec_context.c index 9c62f5a..37bd3d0 100644 --- a/mech_eap/init_sec_context.c +++ b/mech_eap/init_sec_context.c @@ -39,6 +39,8 @@ #include "radius/radius.h" #include "util_radius.h" #include "utils/radius_utils.h" +#include "openssl/err.h" +#include "libmoonshot.h" /* methods allowed for phase1 authentication*/ static const struct eap_method_type allowed_eap_method_types[] = { @@ -78,6 +80,9 @@ policyVariableToFlag(enum eapol_bool_var variable) case EAPOL_altReject: flag = CTX_FLAG_EAP_ALT_REJECT; break; + case EAPOL_eapTriggerStart: + flag = CTX_FLAG_EAP_TRIGGER_START; + break; } return flag; @@ -198,6 +203,7 @@ peerNotifyPending(void *ctx GSSEAP_UNUSED) { } + static struct eapol_callbacks gssEapPolicyCallbacks = { peerGetConfig, peerGetBool, @@ -208,6 +214,8 @@ static struct eapol_callbacks gssEapPolicyCallbacks = { peerSetConfigBlob, peerGetConfigBlob, peerNotifyPending, + NULL, /* eap_param_needed */ + NULL /* eap_notify_cert */ }; @@ -353,6 +361,91 @@ peerProcessChbindResponse(void *context, int code, int nsid, } /* else log failures? */ } +static int cert_to_byte_array(X509 *cert, unsigned char **bytes) +{ + unsigned char *buf; + unsigned char *p; + + int len = i2d_X509(cert, NULL); + if (len <= 0) { + return -1; + } + + p = buf = GSSEAP_MALLOC(len); + if (buf == NULL) { + return -1; + } + + i2d_X509(cert, &buf); + + *bytes = p; + return len; +} + +static int sha256(unsigned char *bytes, int len, unsigned char *hash) +{ + EVP_MD_CTX ctx; + unsigned int hash_len; + + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) { + printf("sha256(init_sec_context.c): EVP_DigestInit_ex failed: %s", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + if (!EVP_DigestUpdate(&ctx, bytes, len)) { + printf("sha256(init_sec_context.c): EVP_DigestUpdate failed: %s", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + if (!EVP_DigestFinal(&ctx, hash, &hash_len)) { + printf("sha256(init_sec_context.c): EVP_DigestFinal failed: %s", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + + return hash_len; +} + + +static int peerValidateServerCert(int ok_so_far, X509* cert, void *ca_ctx) +{ + char *realm = NULL; + unsigned char *cert_bytes = NULL; + int cert_len; + unsigned char hash[32]; + int hash_len; + MoonshotError *error = NULL; + struct eap_peer_config *eap_config = (struct eap_peer_config *) ca_ctx; + char *identity = strdup((const char *) eap_config->identity); + + // Truncate the identity to just the username; make a separate string for the realm. + char* at = strchr(identity, '@'); + if (at != NULL) { + realm = strdup(at + 1); + *at = '\0'; + } + + cert_len = cert_to_byte_array(cert, &cert_bytes); + hash_len = sha256(cert_bytes, cert_len, hash); + GSSEAP_FREE(cert_bytes); + + if (hash_len != 32) { + fprintf(stderr, "peerValidateServerCert: Error: hash_len=%d, not 32!\n", hash_len); + return FALSE; + } + + ok_so_far = moonshot_confirm_ca_certificate(identity, realm, hash, 32, &error); + free(identity); + if (realm != NULL) { + free(realm); + } + + wpa_printf(MSG_INFO, "peerValidateServerCert: Returning %d\n", ok_so_far); + return ok_so_far; +} + + static OM_uint32 peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx) { @@ -458,9 +551,12 @@ peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx) eapPeerConfig->client_cert = (unsigned char *)cred->clientCertificate.value; eapPeerConfig->private_key = (unsigned char *)cred->privateKey.value; } - eapPeerConfig->private_key_passwd = (unsigned char *)cred->password.value; + eapPeerConfig->private_key_passwd = (char *)cred->password.value; } + eapPeerConfig->server_cert_cb = peerValidateServerCert; + eapPeerConfig->server_cert_ctx = eapPeerConfig; + *minor = 0; return GSS_S_COMPLETE; } @@ -835,6 +931,8 @@ eapGssSmInitIdentity(OM_uint32 *minor, OM_uint32 *smFlags) { struct eap_config eapConfig; + memset(&eapConfig, 0, sizeof(eapConfig)); + eapConfig.cert_in_cb = 1; #ifdef GSSEAP_ENABLE_REAUTH if (GSSEAP_SM_STATE(ctx) == GSSEAP_STATE_REAUTHENTICATE) { @@ -851,11 +949,9 @@ eapGssSmInitIdentity(OM_uint32 *minor, GSSEAP_ASSERT((ctx->flags & CTX_FLAG_KRB_REAUTH) == 0); GSSEAP_ASSERT(inputToken == GSS_C_NO_BUFFER); - memset(&eapConfig, 0, sizeof(eapConfig)); - ctx->initiatorCtx.eap = eap_peer_sm_init(ctx, &gssEapPolicyCallbacks, - ctx, + NULL, /* ctx?? */ &eapConfig); if (ctx->initiatorCtx.eap == NULL) { *minor = GSSEAP_PEER_SM_INIT_FAILURE; @@ -1374,3 +1470,4 @@ gss_init_sec_context(OM_uint32 *minor, return major; } +