Ejemplo n.º 1
0
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;
}