#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[] = {
case EAPOL_altReject:
flag = CTX_FLAG_EAP_ALT_REJECT;
break;
+ case EAPOL_eapTriggerStart:
+ flag = CTX_FLAG_EAP_TRIGGER_START;
+ break;
}
return flag;
{
}
+
static struct eapol_callbacks gssEapPolicyCallbacks = {
peerGetConfig,
peerGetBool,
peerSetConfigBlob,
peerGetConfigBlob,
peerNotifyPending,
+ NULL, /* eap_param_needed */
+ NULL /* eap_notify_cert */
};
} /* 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)
{
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;
}
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) {
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;
return major;
}
+