OM_uint32 GSSAPI_CALLCONV gss_pseudo_random(OM_uint32 *minor, gss_ctx_id_t ctx, int prf_key, const gss_buffer_t prf_in, ssize_t desired_output_len, gss_buffer_t prf_out) { OM_uint32 major; if (ctx == GSS_C_NO_CONTEXT) { *minor = EINVAL; return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; } prf_out->length = 0; prf_out->value = NULL; *minor = 0; GSSEAP_MUTEX_LOCK(&ctx->mutex); if (!CTX_IS_ESTABLISHED(ctx)) { major = GSS_S_NO_CONTEXT; *minor = GSSEAP_CONTEXT_INCOMPLETE; goto cleanup; } prf_out->value = GSSEAP_MALLOC(desired_output_len); if (prf_out->value == NULL) { major = GSS_S_FAILURE; *minor = ENOMEM; goto cleanup; } prf_out->length = desired_output_len; major = gssEapPseudoRandom(minor, ctx, prf_key, prf_in, prf_out); cleanup: GSSEAP_MUTEX_UNLOCK(&ctx->mutex); return major; }
static OM_uint32 inquireNegoExKey(OM_uint32 *minor, const gss_ctx_id_t ctx, const gss_OID desired_object, gss_buffer_set_t *dataSet) { OM_uint32 major, tmpMinor; int bInitiatorKey; gss_buffer_desc salt; gss_buffer_desc key = GSS_C_EMPTY_BUFFER; size_t keySize; bInitiatorKey = CTX_IS_INITIATOR(ctx); if (ctx->encryptionType == ENCTYPE_NULL) { major = GSS_S_UNAVAILABLE; *minor = GSSEAP_KEY_UNAVAILABLE; goto cleanup; } /* * If the caller supplied the verify key OID, then we need the acceptor * key if we are the initiator, and vice versa. */ if (desired_object->length == 11 && memcmp(desired_object->elements, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x07", 11) == 0) bInitiatorKey ^= 1; if (bInitiatorKey) { salt.length = NEGOEX_INITIATOR_SALT_LEN; salt.value = NEGOEX_INITIATOR_SALT; } else { salt.length = NEGOEX_ACCEPTOR_SALT_LEN; salt.value = NEGOEX_ACCEPTOR_SALT; } keySize = KRB_KEY_LENGTH(&ctx->rfc3961Key); major = gssEapPseudoRandom(minor, ctx, GSS_C_PRF_KEY_FULL, &salt, keySize, &key); if (GSS_ERROR(major)) goto cleanup; major = gss_add_buffer_set_member(minor, &key, dataSet); if (GSS_ERROR(major)) goto cleanup; major = addEnctypeOidToBufferSet(minor, ctx->encryptionType, dataSet); if (GSS_ERROR(major)) goto cleanup; major = GSS_S_COMPLETE; *minor = 0; cleanup: if (key.value != NULL) { memset(key.value, 0, key.length); gss_release_buffer(&tmpMinor, &key); } if (GSS_ERROR(major)) zeroAndReleaseBufferSet(dataSet); return major; }