#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[] = {
{
}
+static void peerNotifyCert(void *ctx GSSEAP_UNUSED,
+ int depth ,
+ const char *subject GSSEAP_UNUSED,
+ const char *altsubject[] GSSEAP_UNUSED,
+ int num_altsubject GSSEAP_UNUSED,
+ const char *cert_hash GSSEAP_UNUSED,
+ const struct wpabuf *cert GSSEAP_UNUSED)
+{
+ printf("peerNotifyCert: depth=%d; hash=%s (%p)\n", depth, cert_hash, cert_hash);
+}
+
+
static struct eapol_callbacks gssEapPolicyCallbacks = {
peerGetConfig,
peerGetBool,
peerSetConfigBlob,
peerGetConfigBlob,
peerNotifyPending,
+ NULL, /* eap_param_needed */
+ peerNotifyCert
};
} /* 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 peerValidateCA(int ok_so_far, X509* cert, void *ca_ctx)
+{
+ const 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);
+ char* at = strchr(identity, '@');
+
+ if (at != NULL) {
+ *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) {
+ printf("peerValidateCA: Error: hash_len=%d, not 32!\n", hash_len);
+ return FALSE;
+ }
+
+ /* This is ugly, but it works -- anonymous_identity is '@' + realm
+ * (see peerConfigInit)
+ */
+ realm = ((char *) eap_config->anonymous_identity) + 1;
+
+ ok_so_far = moonshot_confirm_ca_certificate(identity, realm, hash, 32, &error);
+
+ printf("peerValidateCA: Returning %d\n", ok_so_far);
+ return ok_so_far;
+}
+
+
static OM_uint32
peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx)
{
eapPeerConfig->private_key_passwd = (char *)cred->password.value;
}
+ eapPeerConfig->validate_ca_cb = peerValidateCA;
+ eapPeerConfig->validate_ca_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;
gssEapTraceStatus( "gss_init_sec_context", major, *minor);
return major;
}
+