コード例 #1
0
ファイル: auth_con.c プロジェクト: Losteven/krb5-test
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)
{
    if (ac->recv_subkey != NULL)
        return krb5_k_key_keyblock(ctx, ac->recv_subkey, keyblock);
    *keyblock = NULL;
    return 0;
}
コード例 #2
0
ファイル: auth_con.c プロジェクト: Losteven/krb5-test
krb5_error_code KRB5_CALLCONV
krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)
{
    if (auth_context->key)
        return krb5_k_key_keyblock(context, auth_context->key, keyblock);
    *keyblock = NULL;
    return 0;
}
コード例 #3
0
ファイル: mk_req_ext.c プロジェクト: Akasurde/krb5
static krb5_error_code
generate_authenticator(krb5_context context, krb5_authenticator *authent,
                       krb5_principal client, krb5_checksum *cksum,
                       krb5_key key, krb5_ui_4 seq_number,
                       krb5_authdata **authorization,
                       krb5_authdata_context ad_context,
                       krb5_enctype *desired_etypes,
                       krb5_enctype tkt_enctype)
{
    krb5_error_code retval;
    krb5_authdata **ext_authdata = NULL;

    authent->client = client;
    authent->checksum = cksum;
    if (key) {
        retval = krb5_k_key_keyblock(context, key, &authent->subkey);
        if (retval)
            return retval;
    } else
        authent->subkey = 0;
    authent->seq_number = seq_number;
    authent->authorization_data = NULL;

    if (ad_context != NULL) {
        retval = krb5_authdata_export_authdata(context,
                                               ad_context,
                                               AD_USAGE_AP_REQ,
                                               &ext_authdata);
        if (retval)
            return retval;
    }

    if (authorization != NULL || ext_authdata != NULL) {
        retval = krb5_merge_authdata(context,
                                     authorization,
                                     ext_authdata,
                                     &authent->authorization_data);
        if (retval) {
            krb5_free_authdata(context, ext_authdata);
            return retval;
        }
        krb5_free_authdata(context, ext_authdata);
    }

    /* Only send EtypeList if we prefer another enctype to tkt_enctype */
    if (desired_etypes != NULL && desired_etypes[0] != tkt_enctype) {
        TRACE_MK_REQ_ETYPES(context, desired_etypes);
        retval = make_etype_list(context, desired_etypes, tkt_enctype,
                                 &authent->authorization_data);
        if (retval)
            return retval;
    }

    return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));
}
コード例 #4
0
ファイル: util_crypt.c プロジェクト: Brainiarc7/pbis
static krb5_error_code
kg_derive_des_enc_key(krb5_context context, krb5_key subkey, krb5_key *out)
{
    krb5_error_code code;
    krb5_keyblock *keyblock;
    unsigned int i;

    *out = NULL;

    code = krb5_k_key_keyblock(context, subkey, &keyblock);
    if (code != 0)
        return code;

    for (i = 0; i < keyblock->length; i++)
        keyblock->contents[i] ^= 0xF0;

    code = krb5_k_create_key(context, keyblock, out);
    krb5_free_keyblock(context, keyblock);
    return code;
}
コード例 #5
0
ファイル: k5unsealiov.c プロジェクト: WeiY/krb5
static OM_uint32
kg_unseal_v1_iov(krb5_context context,
                 OM_uint32 *minor_status,
                 krb5_gss_ctx_id_rec *ctx,
                 gss_iov_buffer_desc *iov,
                 int iov_count,
                 size_t token_wrapper_len,
                 int *conf_state,
                 gss_qop_t *qop_state,
                 int toktype)
{
    OM_uint32 code;
    gss_iov_buffer_t header;
    gss_iov_buffer_t trailer;
    unsigned char *ptr;
    int sealalg;
    int signalg;
    krb5_checksum cksum;
    krb5_checksum md5cksum;
    size_t cksum_len = 0;
    size_t conflen = 0;
    int direction;
    krb5_ui_4 seqnum;
    OM_uint32 retval;
    size_t sumlen;
    krb5_keyusage sign_usage = KG_USAGE_SIGN;

    md5cksum.length = cksum.length = 0;
    md5cksum.contents = cksum.contents = NULL;

    header = kg_locate_header_iov(iov, iov_count, toktype);
    assert(header != NULL);

    trailer = kg_locate_iov(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
    if (trailer != NULL && trailer->buffer.length != 0) {
        *minor_status = (OM_uint32)KRB5_BAD_MSIZE;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if (header->buffer.length < token_wrapper_len + 14) {
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    ptr = (unsigned char *)header->buffer.value + token_wrapper_len;

    signalg  = ptr[0];
    signalg |= ptr[1] << 8;

    sealalg  = ptr[2];
    sealalg |= ptr[3] << 8;

    if (ptr[4] != 0xFF || ptr[5] != 0xFF) {
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if (toktype != KG_TOK_WRAP_MSG && sealalg != 0xFFFF) {
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if (toktype == KG_TOK_WRAP_MSG &&
        !(sealalg == 0xFFFF || sealalg == ctx->sealalg)) {
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
        (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
        (ctx->sealalg == SEAL_ALG_DES3KD &&
         signalg != SGN_ALG_HMAC_SHA1_DES3_KD)||
        (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4 &&
         signalg != SGN_ALG_HMAC_MD5)) {
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    switch (signalg) {
    case SGN_ALG_DES_MAC_MD5:
    case SGN_ALG_MD2_5:
    case SGN_ALG_HMAC_MD5:
        cksum_len = 8;
        if (toktype != KG_TOK_WRAP_MSG)
            sign_usage = 15;
        break;
    case SGN_ALG_3:
        cksum_len = 16;
        break;
    case SGN_ALG_HMAC_SHA1_DES3_KD:
        cksum_len = 20;
        break;
    default:
        *minor_status = 0;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    /* get the token parameters */
    code = kg_get_seq_num(context, ctx->seq, ptr + 14, ptr + 6, &direction,
                          &seqnum);
    if (code != 0) {
        *minor_status = code;
        return GSS_S_BAD_SIG;
    }

    /* decode the message, if SEAL */
    if (toktype == KG_TOK_WRAP_MSG) {
        if (sealalg != 0xFFFF) {
            if (ctx->sealalg == SEAL_ALG_MICROSOFT_RC4) {
                unsigned char bigend_seqnum[4];
                krb5_keyblock *enc_key;
                size_t i;

                store_32_be(seqnum, bigend_seqnum);

                code = krb5_k_key_keyblock(context, ctx->enc, &enc_key);
                if (code != 0) {
                    retval = GSS_S_FAILURE;
                    goto cleanup;
                }

                assert(enc_key->length == 16);

                for (i = 0; i < enc_key->length; i++)
                    ((char *)enc_key->contents)[i] ^= 0xF0;

                code = kg_arcfour_docrypt_iov(context, enc_key, 0,
                                              &bigend_seqnum[0], 4,
                                              iov, iov_count);
                krb5_free_keyblock(context, enc_key);
            } else {
                code = kg_decrypt_iov(context, 0,
                                      ((ctx->gss_flags & GSS_C_DCE_STYLE) != 0),
                                      0 /*EC*/, 0 /*RRC*/,
                                      ctx->enc, KG_USAGE_SEAL, NULL,
                                      iov, iov_count);
            }
            if (code != 0) {
                retval = GSS_S_FAILURE;
                goto cleanup;
            }
        }
        conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype);
    }

    if (header->buffer.length != token_wrapper_len + 14 + cksum_len + conflen) {
        retval = GSS_S_DEFECTIVE_TOKEN;
        goto cleanup;
    }

    /* compute the checksum of the message */

    /* initialize the checksum */

    switch (signalg) {
    case SGN_ALG_DES_MAC_MD5:
    case SGN_ALG_MD2_5:
    case SGN_ALG_DES_MAC:
    case SGN_ALG_3:
        md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
        break;
    case SGN_ALG_HMAC_MD5:
        md5cksum.checksum_type = CKSUMTYPE_HMAC_MD5_ARCFOUR;
        break;
    case SGN_ALG_HMAC_SHA1_DES3_KD:
        md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
        break;
    default:
        abort();
    }

    code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen);
    if (code != 0) {
        retval = GSS_S_FAILURE;
        goto cleanup;
    }
    md5cksum.length = sumlen;

    /* compute the checksum of the message */
    code = kg_make_checksum_iov_v1(context, md5cksum.checksum_type,
                                   cksum_len, ctx->seq, ctx->enc,
                                   sign_usage, iov, iov_count, toktype,
                                   &md5cksum);
    if (code != 0) {
        retval = GSS_S_FAILURE;
        goto cleanup;
    }

    switch (signalg) {
    case SGN_ALG_DES_MAC_MD5:
    case SGN_ALG_3:
        code = kg_encrypt_inplace(context, ctx->seq, KG_USAGE_SEAL,
                                  (g_OID_equal(ctx->mech_used,
                                               gss_mech_krb5_old) ?
                                   ctx->seq->keyblock.contents : NULL),
                                  md5cksum.contents, 16);
        if (code != 0) {
            retval = GSS_S_FAILURE;
            goto cleanup;
        }

        cksum.length = cksum_len;
        cksum.contents = md5cksum.contents + 16 - cksum.length;

        code = k5_bcmp(cksum.contents, ptr + 14, cksum.length);
        break;
    case SGN_ALG_HMAC_SHA1_DES3_KD:
    case SGN_ALG_HMAC_MD5:
        code = k5_bcmp(md5cksum.contents, ptr + 14, cksum_len);
        break;
    default:
        code = 0;
        retval = GSS_S_DEFECTIVE_TOKEN;
        goto cleanup;
        break;
    }

    if (code != 0) {
        code = 0;
        retval = GSS_S_BAD_SIG;
        goto cleanup;
    }

    /*
     * For GSS_C_DCE_STYLE, the caller manages the padding, because the
     * pad length is in the RPC PDU. The value of the padding may be
     * uninitialized. For normal GSS, the last bytes of the decrypted
     * data contain the pad length. kg_fixup_padding_iov() will find
     * this and fixup the last data IOV appropriately.
     */
    if (toktype == KG_TOK_WRAP_MSG &&
        (ctx->gss_flags & GSS_C_DCE_STYLE) == 0) {
        retval = kg_fixup_padding_iov(&code, iov, iov_count);
        if (retval != GSS_S_COMPLETE)
            goto cleanup;
    }

    if (conf_state != NULL)
        *conf_state = (sealalg != 0xFFFF);

    if (qop_state != NULL)
        *qop_state = GSS_C_QOP_DEFAULT;

    if ((ctx->initiate && direction != 0xff) ||
        (!ctx->initiate && direction != 0)) {
        *minor_status = (OM_uint32)G_BAD_DIRECTION;
        retval = GSS_S_BAD_SIG;
    }

    code = 0;
    retval = g_order_check(&ctx->seqstate, (gssint_uint64)seqnum);

cleanup:
    krb5_free_checksum_contents(context, &md5cksum);

    *minor_status = code;

    return retval;
}
コード例 #6
0
ファイル: context_lucid.c プロジェクト: Xyratex/lustre-stable
/*
 * Function to derive a new key from a given key and given constant data.
 */
static krb5_error_code
derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out,
		 int usage, char extra)
{
	krb5_error_code code;
	unsigned char constant_data[K5CLENGTH];
	krb5_data datain;
	int keylength __attribute__ ((unused));
#ifdef HAVE_KRB5
	void *enc;
#endif
	krb5_keyblock kin;  /* must send krb5_keyblock, not lucid! */
#if defined(HAVE_HEIMDAL) || HAVE_KRB5INT_DERIVE_KEY
	krb5_context kcontext;
	krb5_keyblock *outkey;
#else
	krb5_keyblock kout;
#endif
#if HAVE_KRB5INT_DERIVE_KEY
	krb5_key key_in, key_out;
#endif

	/*
	 * XXX Hack alert.  We don't have "legal" access to these
	 * values and structures located in libk5crypto
	 */
	switch (in->type) {
	case ENCTYPE_DES3_CBC_SHA1:
#ifdef HAVE_KRB5
	case ENCTYPE_DES3_CBC_RAW:
#endif
		keylength = 24;
#ifdef HAVE_KRB5
		enc = &krb5int_enc_des3;
#endif
		break;
	case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
		keylength = 16;
#ifdef HAVE_KRB5
		enc = &krb5int_enc_aes128;
#endif
		break;
	case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
		keylength = 32;
#ifdef HAVE_KRB5
		enc = &krb5int_enc_aes256;
#endif
		break;
	default:
		code = KRB5_BAD_ENCTYPE;
		goto out;
	}

	/* Convert to correct format for call to krb5_derive_key */
	key_lucid_to_krb5(in, &kin);

	datain.data = (char *) constant_data;
	datain.length = K5CLENGTH;

	((char *)(datain.data))[0] = (usage>>24)&0xff;
	((char *)(datain.data))[1] = (usage>>16)&0xff;
	((char *)(datain.data))[2] = (usage>>8)&0xff;
	((char *)(datain.data))[3] = usage&0xff;

	((char *)(datain.data))[4] = (char) extra;

	/* Step 1: Init context */
	/* Heimdal and newer MIT Kerberos require kcontext */
#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
	code = krb5_init_context(&kcontext);
	if (code)
		goto out;
#endif

	/* Step 2: Get the derived key */
#ifdef HAVE_KRB5
#if HAVE_KRB5INT_DERIVE_KEY
	code = krb5_k_create_key(kcontext, &kin, &key_in);
	if (code)
		goto out;

	code = ll_krb5int_derive_key(enc, key_in, &key_out, &datain,
				     DERIVE_RFC3961);

	krb5_k_free_key(kcontext, key_in);
	if (code == 0) {
		krb5_k_key_keyblock(kcontext, key_out, &outkey);
		krb5_k_free_key(kcontext, key_out);
	}
#else  /* !HAVE_KRB5INT_DERIVE_KEY */
	out->length = keylength;
	out->type = in->type;

	key_lucid_to_krb5(out, &kout);

	code = krb5_derive_key(enc, &kin, &kout, &datain);
#endif	/* HAVE_KRB5INT_DERIVE_KEY */
#else	/* !defined(HAVE_KRB5) */
	code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
#endif	/* defined(HAVE_KRB5) */

	if (code)
		goto out;

	/* Step 3: Copy the key to out */
#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
	code = key_krb5_to_lucid(outkey, out);
	krb5_free_keyblock(kcontext, outkey);
#else	/* !defined(HAVE_KRB5) */
	code = key_krb5_to_lucid(&kout, out);
#endif	/* defined(HAVE_KRB5) */

	/* Step 4: Free the context */
#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL)
	krb5_free_context(kcontext);
#endif

  out:
	if (code)
		printerr(0, "ERROR: %s: returning error %d (%s)\n",
			 __FUNCTION__, code, error_message(code));
	return (code);
}