static bool getAttributeId(const gss_buffer_t desc, gss_eap_attrid *attrid) { char *strAttr, *s; int canon, code; if (desc->length == 0) return false; canon = isdigit(*(char *)desc->value); /* need to duplicate because attr may not be NUL terminated */ strAttr = (char *)GSSEAP_MALLOC((canon ? 5 : 0) + desc->length + 1); if (strAttr == NULL) throw new std::bad_alloc(); s = strAttr; if (canon) { memcpy(s, "Attr-", 5); s += 5; } memcpy(s, desc->value, desc->length); s += desc->length; *s = '\0'; code = rs_attr_parse_name(strAttr, &attrid->second, &attrid->first); GSSEAP_FREE(strAttr); return (code == RSE_OK); }
int gssEapDecrypt(krb5_context context, int dce_style, size_t ec, size_t rrc, #ifdef HAVE_HEIMDAL_VERSION krb5_crypto crypto, #else krb5_keyblock *crypto, #endif int usage, gss_iov_buffer_desc *iov, int iov_count) { krb5_error_code code; size_t kiov_count; krb5_crypto_iov *kiov; code = mapIov(context, dce_style, ec, rrc, crypto, iov, iov_count, &kiov, &kiov_count); if (code != 0) goto cleanup; #ifdef HAVE_HEIMDAL_VERSION code = krb5_decrypt_iov_ivec(context, crypto, usage, kiov, kiov_count, NULL); #else code = krb5_c_decrypt_iov(context, crypto, usage, NULL, kiov, kiov_count); #endif cleanup: if (kiov != NULL) GSSEAP_FREE(kiov); return code; }
OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred) { OM_uint32 tmpMinor; gss_cred_id_t cred = *pCred; if (cred == GSS_C_NO_CREDENTIAL) { return GSS_S_COMPLETE; } gssEapReleaseName(&tmpMinor, &cred->name); gssEapReleaseName(&tmpMinor, &cred->target); zeroAndReleasePassword(&cred->password); #ifndef MECH_EAP zeroAndReleasePassword(&cred->deleg_assertions); #endif gss_release_buffer(&tmpMinor, &cred->radiusConfigFile); gss_release_buffer(&tmpMinor, &cred->radiusConfigStanza); gss_release_buffer(&tmpMinor, &cred->caCertificate); gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint); gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint); GSSEAP_MUTEX_DESTROY(&cred->mutex); memset(cred, 0, sizeof(*cred)); GSSEAP_FREE(cred); *pCred = NULL; *minor = 0; return GSS_S_COMPLETE; }
static void zeroAndReleasePassword(gss_buffer_t password) { if (password->value != NULL) { memset(password->value, 0, password->length); GSSEAP_FREE(password->value); } password->value = NULL; password->length = 0; }
static JSONObject avpToJson(rs_const_avp *vp) { JSONObject obj; gss_eap_attrid attrid; GSSEAP_ASSERT(rs_avp_length(vp) <= RS_MAX_STRING_LEN); switch (rs_avp_typeof(vp)) { case RS_TYPE_INTEGER: obj.set("value", rs_avp_integer_value(vp)); break; case RS_TYPE_DATE: obj.set("value", rs_avp_date_value(vp)); break; case RS_TYPE_STRING: obj.set("value", rs_avp_string_value(vp)); break; default: { char *b64; if (base64Encode(rs_avp_octets_value_const_ptr(vp), rs_avp_length(vp), &b64) < 0) throw std::bad_alloc(); obj.set("value", b64); GSSEAP_FREE(b64); break; } } attrid = avpToAttrId(vp); obj.set("type", attrid.second); if (attrid.first != 0) obj.set("vendor", attrid.first); return obj; }
OM_uint32 gssEapDecodeInnerTokens(OM_uint32 *minor, const gss_buffer_t buffer, struct gss_eap_token_buffer_set *tokens) { OM_uint32 major, tmpMinor; unsigned char *p; size_t count = 0; size_t remain; tokens->buffers.count = 0; tokens->buffers.elements = NULL; tokens->types = NULL; if (buffer->length == 0) { major = GSS_S_COMPLETE; goto cleanup; } p = (unsigned char *)buffer->value; remain = buffer->length; do { OM_uint32 *ntypes; gss_buffer_desc tokenBuffer, *newTokenBuffers; if (remain < 8) { major = GSS_S_DEFECTIVE_TOKEN; *minor = GSSEAP_TOK_TRUNC; goto cleanup; } if (tokens->buffers.count <= count) { if (count == 0) count = 1; else count *= 2; ntypes = GSSEAP_MALLOC(count * sizeof(OM_uint32)); if (ntypes == NULL) { major = GSS_S_FAILURE; *minor = ENOMEM; goto cleanup; } if (tokens->types != NULL) { memcpy(ntypes, tokens->types, tokens->buffers.count * sizeof(OM_uint32)); GSSEAP_FREE(tokens->types); } tokens->types = ntypes; newTokenBuffers = GSSEAP_MALLOC(count * sizeof(gss_buffer_desc)); if (newTokenBuffers == NULL) { major = GSS_S_FAILURE; *minor = ENOMEM; goto cleanup; } if (tokens->buffers.elements != NULL) { memcpy(newTokenBuffers, tokens->buffers.elements, tokens->buffers.count * sizeof(gss_buffer_desc)); GSSEAP_FREE(tokens->buffers.elements); } tokens->buffers.elements = newTokenBuffers; } tokens->types[tokens->buffers.count] = load_uint32_be(&p[0]); tokenBuffer.length = load_uint32_be(&p[4]); if (remain < 8 + tokenBuffer.length) { major = GSS_S_DEFECTIVE_TOKEN; *minor = GSSEAP_TOK_TRUNC; goto cleanup; } tokenBuffer.value = &p[8]; tokens->buffers.elements[tokens->buffers.count] = tokenBuffer; tokens->buffers.count++; p += 8 + tokenBuffer.length; remain -= 8 + tokenBuffer.length; } while (remain != 0); major = GSS_S_COMPLETE; *minor = 0; cleanup: if (GSS_ERROR(major)) gssEapReleaseInnerTokens(&tmpMinor, tokens, 0); return major; }
OM_uint32 gssEapPseudoRandom(OM_uint32 *minor, gss_const_ctx_id_t ctx, int prf_key, const gss_buffer_t prf_in, gss_buffer_t prf_out) { krb5_error_code code; int i; OM_uint32 tmpMinor; size_t prflen; krb5_data t, ns; unsigned char *p; krb5_context krbContext; ssize_t desired_output_len = prf_out->length; #ifdef HAVE_HEIMDAL_VERSION krb5_crypto krbCrypto = NULL; #endif *minor = 0; GSSEAP_KRB_INIT(&krbContext); KRB_DATA_INIT(&t); KRB_DATA_INIT(&ns); if (prf_key != GSS_C_PRF_KEY_PARTIAL && prf_key != GSS_C_PRF_KEY_FULL) { code = GSSEAP_BAD_PRF_KEY; goto cleanup; } #ifdef HAVE_HEIMDAL_VERSION code = krb5_crypto_prf_length(krbContext, ctx->encryptionType, &prflen); #else code = krb5_c_prf_length(krbContext, ctx->encryptionType, &prflen); #endif if (code != 0) goto cleanup; ns.length = 4 + prf_in->length; ns.data = GSSEAP_MALLOC(ns.length); if (ns.data == NULL) { code = ENOMEM; goto cleanup; } #ifdef HAVE_HEIMDAL_VERSION code = krb5_crypto_init(krbContext, &ctx->rfc3961Key, 0, &krbCrypto); if (code != 0) goto cleanup; #else t.length = prflen; t.data = GSSEAP_MALLOC(t.length); if (t.data == NULL) { code = ENOMEM; goto cleanup; } #endif memcpy((unsigned char *)ns.data + 4, prf_in->value, prf_in->length); i = 0; p = (unsigned char *)prf_out->value; while (desired_output_len > 0) { store_uint32_be(i, ns.data); #ifdef HAVE_HEIMDAL_VERSION code = krb5_crypto_prf(krbContext, krbCrypto, &ns, &t); #else code = krb5_c_prf(krbContext, &ctx->rfc3961Key, &ns, &t); #endif if (code != 0) goto cleanup; memcpy(p, t.data, MIN(t.length, desired_output_len)); p += t.length; desired_output_len -= t.length; i++; } cleanup: if (code != 0) gss_release_buffer(&tmpMinor, prf_out); if (ns.data != NULL) { memset(ns.data, 0, ns.length); GSSEAP_FREE(ns.data); } #ifdef HAVE_HEIMDAL_VERSION krb5_crypto_destroy(krbContext, krbCrypto); krb5_data_free(&t); #else if (t.data != NULL) { memset(t.data, 0, t.length); GSSEAP_FREE(t.data); } #endif *minor = code; return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; }