From: Sam Hartman Date: Fri, 20 Sep 2013 17:04:12 +0000 (-0400) Subject: Merge remote-tracking branch 'origin/eap-tls' X-Git-Tag: 0.9.2~39 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=commitdiff_plain;h=26311844916784cc0781b1a304b590dff5742fcb Merge remote-tracking branch 'origin/eap-tls' The eap-tls branch includes build dependencies on openssl which we need for the sha2 hash support in IDP certs. The eap-tls changes are not widely exposed, but to the extent they are present are harmless. Conflicts: libeap/Makefile.am mech_eap/Makefile.am mech_eap/gssapiP_eap.h mech_eap/init_sec_context.c --- 26311844916784cc0781b1a304b590dff5742fcb diff --cc libeap/Makefile.am index 7b235c9,8cc9fb5..a51424e --- a/libeap/Makefile.am +++ b/libeap/Makefile.am @@@ -64,37 -64,38 +64,38 @@@ SOURCES_peer += src/eap_peer/eap_tls_co src/eap_peer/mschapv2.h \ src/eap_peer/tncc.h -CFLAGS += -DEAP_TLS -CFLAGS += -DEAP_PEAP -CFLAGS += -DEAP_TTLS -CFLAGS += -DEAP_MD5 -CFLAGS += -DEAP_MSCHAPv2 -CFLAGS += -DEAP_GTC -CFLAGS += -DEAP_OTP -CFLAGS += -DEAP_LEAP -CFLAGS += -DEAP_PSK -CFLAGS += -DEAP_PAX -CFLAGS += -DEAP_SAKE -CFLAGS += -DEAP_GPSK -DEAP_GPSK_SHA256 +AM_CFLAGS = -DEAP_TLS +AM_CFLAGS += -DEAP_PEAP +AM_CFLAGS += -DEAP_TTLS +AM_CFLAGS += -DEAP_MD5 +AM_CFLAGS += -DEAP_MSCHAPv2 +AM_CFLAGS += -DEAP_GTC +AM_CFLAGS += -DEAP_OTP +AM_CFLAGS += -DEAP_LEAP +AM_CFLAGS += -DEAP_PSK +AM_CFLAGS += -DEAP_PAX +AM_CFLAGS += -DEAP_SAKE +AM_CFLAGS += -DEAP_GPSK -DEAP_GPSK_SHA256 -CFLAGS += -DEAP_SERVER_IDENTITY -CFLAGS += -DEAP_SERVER_TLS -CFLAGS += -DEAP_SERVER_PEAP -CFLAGS += -DEAP_SERVER_TTLS -CFLAGS += -DEAP_SERVER_MD5 -CFLAGS += -DEAP_SERVER_MSCHAPV2 -CFLAGS += -DEAP_SERVER_GTC -CFLAGS += -DEAP_SERVER_PSK -CFLAGS += -DEAP_SERVER_PAX -CFLAGS += -DEAP_SERVER_SAKE -CFLAGS += -DEAP_SERVER_GPSK -DEAP_SERVER_GPSK_SHA256 +AM_CFLAGS += -DEAP_SERVER_IDENTITY +AM_CFLAGS += -DEAP_SERVER_TLS +AM_CFLAGS += -DEAP_SERVER_PEAP +AM_CFLAGS += -DEAP_SERVER_TTLS +AM_CFLAGS += -DEAP_SERVER_MD5 +AM_CFLAGS += -DEAP_SERVER_MSCHAPV2 +AM_CFLAGS += -DEAP_SERVER_GTC +AM_CFLAGS += -DEAP_SERVER_PSK +AM_CFLAGS += -DEAP_SERVER_PAX +AM_CFLAGS += -DEAP_SERVER_SAKE +AM_CFLAGS += -DEAP_SERVER_GPSK -DEAP_SERVER_GPSK_SHA256 -CFLAGS += -DIEEE8021X_EAPOL -CFLAGS += -DCONFIG_IPV6 +AM_CFLAGS += -DIEEE8021X_EAPOL +AM_CFLAGS += -DCONFIG_IPV6 -CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH -CFLAGS += -DCONFIG_INTERNAL_SHA1 -CFLAGS += -DEAP_TLS_OPENSSL -CFLAGS += -DPKCS12_FUNCS +AM_CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH - AM_CFLAGS += -DCONFIG_CRYPTO_INTERNAL - AM_CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT ++AM_CFLAGS += -DCONFIG_INTERNAL_SHA1 ++AM_CFLAGS += -DEAP_TLS_OPENSSL ++AM_CFLAGS += -DPKCS12_FUNCS UTILS_SRCS = src/utils/base64.c \ src/utils/common.c \ diff --cc mech_eap/Makefile.am index 860d914,a652182..145188f --- a/mech_eap/Makefile.am +++ b/mech_eap/Makefile.am @@@ -42,7 -42,7 +42,8 @@@ mech_eap_la_CXXFLAGS += @TARGET_CFLAGS@ $(EAP_CFLAGS) mech_eap_la_LDFLAGS = -avoid-version -module \ -export-symbols $(GSSEAP_EXPORTS) -no-undefined \ - @KRB5_LDFLAGS@ @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@ - @RADSEC_LDFLAGS@ @OPENSSL_LDFLAGS@ @TARGET_LDFLAGS@ ++ @KRB5_LDFLAGS@ @RADSEC_LDFLAGS@ @TARGET_LDFLAGS@ @OPENSSL_LDFLAGS@ ++ if TARGET_WINDOWS mech_eap_la_LDFLAGS += -debug endif diff --cc mech_eap/gssapiP_eap.h index 19f1770,eb7e7db..8a997d5 --- a/mech_eap/gssapiP_eap.h +++ b/mech_eap/gssapiP_eap.h @@@ -177,16 -197,18 +181,21 @@@ struct gss_cred_id_struc #define CTX_FLAG_EAP_PORT_ENABLED 0x00400000 #define CTX_FLAG_EAP_ALT_ACCEPT 0x00800000 #define CTX_FLAG_EAP_ALT_REJECT 0x01000000 +#define CTX_FLAG_EAP_CHBIND_ACCEPT 0x02000000 #define CTX_FLAG_EAP_MASK 0xFFFF0000 + #define CONFIG_BLOB_CLIENT_CERT 0 + #define CONFIG_BLOB_PRIVATE_KEY 1 + #define CONFIG_BLOB_MAX 2 + struct gss_eap_initiator_ctx { unsigned int idleWhile; struct eap_peer_config eapPeerConfig; struct eap_sm *eap; struct wpabuf reqData; + struct wpabuf *chbindData; + unsigned int chbindReqFlags; + struct wpa_config_blob configBlobs[CONFIG_BLOB_MAX]; }; #ifdef GSSEAP_ENABLE_ACCEPTOR diff --cc mech_eap/init_sec_context.c index f22214d,a67d381..39929a6 --- a/mech_eap/init_sec_context.c +++ b/mech_eap/init_sec_context.c @@@ -197,143 -204,6 +207,143 @@@ static struct eapol_callbacks gssEapPol extern int wpa_debug_level; #endif +#define CHBIND_SERVICE_NAME_FLAG 0x01 +#define CHBIND_HOST_NAME_FLAG 0x02 +#define CHBIND_SERVICE_SPECIFIC_FLAG 0x04 +#define CHBIND_REALM_NAME_FLAG 0x08 + - tatic OM_uint32 ++static OM_uint32 +peerInitEapChannelBinding(OM_uint32 *minor, gss_ctx_id_t ctx) +{ + struct wpabuf *buf = NULL; + unsigned int chbindReqFlags = 0; + krb5_principal princ = NULL; + gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; + OM_uint32 major = GSS_S_COMPLETE; + krb5_context krbContext = NULL; + + /* XXX is this check redundant? */ + if (ctx->acceptorName == GSS_C_NO_NAME) { + major = GSS_S_BAD_NAME; + *minor = GSSEAP_NO_ACCEPTOR_NAME; + goto cleanup; + } + + princ = ctx->acceptorName->krbPrincipal; + + krbPrincComponentToGssBuffer(princ, 0, &nameBuf); + if (nameBuf.length > 0) { + major = gssEapRadiusAddAttr(minor, &buf, PW_GSS_ACCEPTOR_SERVICE_NAME, + 0, &nameBuf); + if (GSS_ERROR(major)) + goto cleanup; + + chbindReqFlags |= CHBIND_SERVICE_NAME_FLAG; + } + + krbPrincComponentToGssBuffer(princ, 1, &nameBuf); + if (nameBuf.length > 0) { + major = gssEapRadiusAddAttr(minor, &buf, PW_GSS_ACCEPTOR_HOST_NAME, + 0, &nameBuf); + if (GSS_ERROR(major)) + goto cleanup; + + chbindReqFlags |= CHBIND_HOST_NAME_FLAG; + } + + GSSEAP_KRB_INIT(&krbContext); + + *minor = krbPrincUnparseServiceSpecifics(krbContext, princ, &nameBuf); + if (*minor != 0) + goto cleanup; + + if (nameBuf.length > 0) { + major = gssEapRadiusAddAttr(minor, &buf, + PW_GSS_ACCEPTOR_SERVICE_SPECIFICS, + 0, &nameBuf); + if (GSS_ERROR(major)) + goto cleanup; + + chbindReqFlags |= CHBIND_SERVICE_SPECIFIC_FLAG; + } + + krbFreeUnparsedName(krbContext, &nameBuf); + krbPrincRealmToGssBuffer(princ, &nameBuf); + + if (nameBuf.length > 0) { + major = gssEapRadiusAddAttr(minor, &buf, + PW_GSS_ACCEPTOR_REALM_NAME, + 0, &nameBuf); + chbindReqFlags |= CHBIND_REALM_NAME_FLAG; + } + + if (chbindReqFlags == 0) { + major = GSS_S_BAD_NAME; + *minor = GSSEAP_BAD_ACCEPTOR_NAME; + goto cleanup; + } + + ctx->initiatorCtx.chbindData = buf; + ctx->initiatorCtx.chbindReqFlags = chbindReqFlags; + + buf = NULL; + + major = GSS_S_COMPLETE; + *minor = 0; + +cleanup: + krbFreeUnparsedName(krbContext, &nameBuf); + wpabuf_free(buf); + + return major; +} + +static void +peerProcessChbindResponse(void *context, int code, int nsid, + u8 *data, size_t len) +{ + radius_parser msg; + gss_ctx_id_t ctx = (gss_ctx_id_t )context; + void *vsadata; + u8 type; + u32 vendor_id; + u32 chbindRetFlags = 0; + size_t vsadata_len; + + if (nsid != CHBIND_NSID_RADIUS) + return; + + msg = radius_parser_start(data, len); + if (msg == NULL) + return; + + while (radius_parser_parse_tlv(msg, &type, &vendor_id, &vsadata, + &vsadata_len) == 0) { + switch (type) { + case PW_GSS_ACCEPTOR_SERVICE_NAME: + chbindRetFlags |= CHBIND_SERVICE_NAME_FLAG; + break; + case PW_GSS_ACCEPTOR_HOST_NAME: + chbindRetFlags |= CHBIND_HOST_NAME_FLAG; + break; + case PW_GSS_ACCEPTOR_SERVICE_SPECIFICS: + chbindRetFlags |= CHBIND_SERVICE_SPECIFIC_FLAG; + break; + case PW_GSS_ACCEPTOR_REALM_NAME: + chbindRetFlags |= CHBIND_REALM_NAME_FLAG; + break; + } + } + + radius_parser_finish(msg); + + if (code == CHBIND_CODE_SUCCESS && + ((chbindRetFlags & ctx->initiatorCtx.chbindReqFlags) == ctx->initiatorCtx.chbindReqFlags)) { + ctx->flags |= CTX_FLAG_EAP_CHBIND_ACCEPT; + ctx->gssFlags |= GSS_C_MUTUAL_FLAG; + } /* else log failures? */ +} + static OM_uint32 peerConfigInit(OM_uint32 *minor, gss_ctx_id_t ctx) { @@@ -398,26 -271,26 +411,46 @@@ eapPeerConfig->subject_match = (unsigned char *)cred->subjectNameConstraint.value; eapPeerConfig->altsubject_match = (unsigned char *)cred->subjectAltNameConstraint.value; + /* eap channel binding */ + if (ctx->initiatorCtx.chbindData != NULL) { + struct eap_peer_chbind_config *chbind_config = + (struct eap_peer_chbind_config *)GSSEAP_MALLOC(sizeof(struct eap_peer_chbind_config)); + if (chbind_config == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + + chbind_config->req_data = wpabuf_mhead_u8(ctx->initiatorCtx.chbindData); + chbind_config->req_data_len = wpabuf_len(ctx->initiatorCtx.chbindData); + chbind_config->nsid = CHBIND_NSID_RADIUS; + chbind_config->response_cb = &peerProcessChbindResponse; + chbind_config->ctx = ctx; + eapPeerConfig->chbind_config = chbind_config; + eapPeerConfig->chbind_config_len = 1; + } else { + eapPeerConfig->chbind_config = NULL; + eapPeerConfig->chbind_config_len = 0; + } + if (cred->flags & CRED_FLAG_CERTIFICATE) { + /* + * CRED_FLAG_CONFIG_BLOB is an internal flag which will be used in the + * future to directly pass certificate and private key data to the + * EAP implementation, rather than an indirected string pointer. + */ + if (cred->flags & CRED_FLAG_CONFIG_BLOB) { + eapPeerConfig->client_cert = (unsigned char *)"blob://client-cert"; + configBlobs[CONFIG_BLOB_CLIENT_CERT].data = cred->clientCertificate.value; + configBlobs[CONFIG_BLOB_CLIENT_CERT].len = cred->clientCertificate.length; + + eapPeerConfig->client_cert = (unsigned char *)"blob://private-key"; + configBlobs[CONFIG_BLOB_PRIVATE_KEY].data = cred->clientCertificate.value; + configBlobs[CONFIG_BLOB_PRIVATE_KEY].len = cred->privateKey.length; + } else { + 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; + } *minor = 0; return GSS_S_COMPLETE;