Beispiel #1
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_error_code ret;
    krb5_keyblock key;
    krb5_crypto crypto;
    size_t length;
    krb5_data input, output, output2;
    krb5_enctype etype = ETYPE_AES256_CTS_HMAC_SHA1_96;

    ret = krb5_init_context(&context);
    if (ret)
	errx(1, "krb5_init_context %d", ret);

    ret = krb5_generate_random_keyblock(context, etype, &key);
    if (ret)
	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");

    ret = krb5_crypto_prf_length(context, etype, &length);
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_prf_length");

    ret = krb5_crypto_init(context, &key, 0, &crypto);
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_init");

    input.data = rk_UNCONST("foo");
    input.length = 3;

    ret = krb5_crypto_prf(context, crypto, &input, &output);
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_prf");

    ret = krb5_crypto_prf(context, crypto, &input, &output2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_prf");

    if (krb5_data_cmp(&output, &output2) != 0)
	krb5_errx(context, 1, "krb5_data_cmp");

    krb5_data_free(&output);
    krb5_data_free(&output2);

    krb5_crypto_destroy(context, crypto);

    krb5_free_keyblock_contents(context, &key);

    krb5_free_context(context);

    return 0;
}
Beispiel #2
0
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_pseudo_random(OM_uint32 *minor_status,
		       gss_ctx_id_t context_handle,
		       int prf_key,
		       const gss_buffer_t prf_in,
		       ssize_t desired_output_len,
		       gss_buffer_t prf_out)
{
    gsskrb5_ctx ctx = (gsskrb5_ctx)context_handle;
    krb5_context context;
    krb5_error_code ret;
    krb5_crypto crypto;
    krb5_data input, output;
    uint32_t num;
    unsigned char *p;
    krb5_keyblock *key = NULL;

    if (ctx == NULL) {
	*minor_status = 0;
	return GSS_S_NO_CONTEXT;
    }

    if (desired_output_len <= 0) {
	*minor_status = 0;
	return GSS_S_FAILURE;
    }

    GSSAPI_KRB5_INIT (&context);

    switch(prf_key) {
    case GSS_C_PRF_KEY_FULL:
	_gsskrb5i_get_acceptor_subkey(ctx, context, &key);
	break;
    case GSS_C_PRF_KEY_PARTIAL:
	_gsskrb5i_get_initiator_subkey(ctx, context, &key);
	break;
    default:
	_gsskrb5_set_status(EINVAL, "unknown kerberos prf_key");
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    if (key == NULL) {
	_gsskrb5_set_status(EINVAL, "no prf_key found");
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    ret = krb5_crypto_init(context, key, 0, &crypto);
    krb5_free_keyblock (context, key);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    prf_out->value = malloc(desired_output_len);
    if (prf_out->value == NULL) {
	_gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
	*minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
	krb5_crypto_destroy(context, crypto);
	return GSS_S_FAILURE;
    }
    prf_out->length = desired_output_len;

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    input.length = prf_in->length + 4;
    input.data = malloc(prf_in->length + 4);
    if (input.data == NULL) {
	OM_uint32 junk;
	_gsskrb5_set_status(GSS_KRB5_S_KG_INPUT_TOO_LONG, "Out of memory");
	*minor_status = GSS_KRB5_S_KG_INPUT_TOO_LONG;
	gss_release_buffer(&junk, prf_out);
	krb5_crypto_destroy(context, crypto);
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	return GSS_S_FAILURE;
    }
    memcpy(((unsigned char *)input.data) + 4, prf_in->value, prf_in->length);

    num = 0;
    p = prf_out->value;
    while(desired_output_len > 0) {
	_gsskrb5_encode_om_uint32(num, input.data);
	ret = krb5_crypto_prf(context, crypto, &input, &output);
	if (ret) {
	    OM_uint32 junk;
	    *minor_status = ret;
	    free(input.data);
	    gss_release_buffer(&junk, prf_out);
	    krb5_crypto_destroy(context, crypto);
	    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	    return GSS_S_FAILURE;
	}
	memcpy(p, output.data, min(desired_output_len, output.length));
	p += output.length;
	desired_output_len -= output.length;
	krb5_data_free(&output);
	num++;
    }
    free(input.data);

    krb5_crypto_destroy(context, crypto);

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    return GSS_S_COMPLETE;
}
Beispiel #3
0
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;
}