예제 #1
0
static int
krb_enc_iov(krb5_context context,
	    krb5_crypto crypto,
	    unsigned usage,
	    krb5_data *cipher,
	    krb5_data *clear)
{
    krb5_crypto_iov iov[3];
    int ret;
    char *p;
    size_t len;

    p = cipher->data;
    len = cipher->length;

    iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
    krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
    iov[0].data.data = emalloc(iov[0].data.length);
    memcpy(iov[0].data.data, p, iov[0].data.length);
    p += iov[0].data.length;
    len -= iov[0].data.length;

    iov[1].flags = KRB5_CRYPTO_TYPE_TRAILER;
    krb5_crypto_length(context, crypto, iov[1].flags, &iov[1].data.length);
    iov[1].data.data = emalloc(iov[1].data.length);
    memcpy(iov[1].data.data, p + len - iov[1].data.length, iov[1].data.length);
    len -= iov[1].data.length;

    iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
    iov[2].data.length = len;
    iov[2].data.data = emalloc(len);
    memcpy(iov[2].data.data, p, len);

    ret = krb5_decrypt_iov_ivec(context, crypto, usage,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb_enc_iov decrypt iov failed: %d", ret);

    if (clear->length != iov[2].data.length)
	errx(1, "length incorrect");

    p = clear->data;
    if (memcmp(iov[2].data.data, p, iov[2].data.length) != 0)
	errx(1, "iov[2] incorrect");

    free(iov[0].data.data);
    free(iov[1].data.data);
    free(iov[2].data.data);


    return 0;
}
예제 #2
0
static int
krb_checksum_iov(krb5_context context,
		 krb5_crypto crypto,
		 unsigned usage,
		 krb5_data *plain)
{
    krb5_crypto_iov iov[4];
    int ret;
    char *p;
    size_t len;

    p = plain->data;
    len = plain->length;

    iov[0].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
    krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
    iov[0].data.data = emalloc(iov[0].data.length);

    iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
    iov[1].data.length = len;
    iov[1].data.data = p;

    iov[2].flags = KRB5_CRYPTO_TYPE_TRAILER;
    krb5_crypto_length(context, crypto, iov[0].flags, &iov[2].data.length);
    iov[2].data.data = malloc(iov[2].data.length);

    ret = krb5_create_checksum_iov(context, crypto, usage,
				   iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_create_checksum_iov failed");

    ret = krb5_verify_checksum_iov(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_verify_checksum_iov");

    free(iov[0].data.data);
    free(iov[2].data.data);

    return 0;
}
예제 #3
0
static int
iov_test(krb5_context context)
{
    krb5_enctype enctype = KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
    krb5_error_code ret;
    krb5_crypto crypto;
    krb5_keyblock key;
    krb5_data signonly, in, in2;
    krb5_crypto_iov iov[6];
    size_t len, i;
    unsigned char *base, *p;

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

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


    ret = krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &len);
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_length");

    signonly.data = "This should be signed";
    signonly.length = strlen(signonly.data);
    in.data = "inputdata";
    in.length = strlen(in.data);

    in2.data = "INPUTDATA";
    in2.length = strlen(in2.data);


    memset(iov, 0, sizeof(iov));

    iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
    iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
    iov[1].data = in;
    iov[2].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
    iov[2].data = signonly;
    iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY;
    iov[4].flags = KRB5_CRYPTO_TYPE_PADDING;
    iov[5].flags = KRB5_CRYPTO_TYPE_TRAILER;

    ret = krb5_crypto_length_iov(context, crypto, iov,
				 sizeof(iov)/sizeof(iov[0]));
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_length_iov");

    for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
	    continue;
	len += iov[i].data.length;
    }

    base = emalloc(len);

    /*
     * Allocate data for the fields
     */

    for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
	    continue;;
	iov[i].data.data = p;
	p += iov[i].data.length;
    }
    assert(iov[1].data.length == in.length);
    memcpy(iov[1].data.data, in.data, iov[1].data.length);

    /*
     * Encrypt
     */

    ret = krb5_encrypt_iov_ivec(context, crypto, 7, iov,
				sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec");

    /*
     * Decrypt
     */

    ret = krb5_decrypt_iov_ivec(context, crypto, 7,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec");

    /*
     * Verify data
     */

    if (krb5_data_cmp(&iov[1].data, &in) != 0)
	krb5_errx(context, 1, "decrypted data not same");

    /*
     * Free memory
     */

    free(base);

    /* Set up for second try */

    iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
    iov[3].data = in;

    ret = krb5_crypto_length_iov(context, crypto,
				 iov, sizeof(iov)/sizeof(iov[0]));
    if (ret)
	krb5_err(context, 1, ret, "krb5_crypto_length_iov");

    for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
	    continue;
	len += iov[i].data.length;
    }

    base = emalloc(len);

    /*
     * Allocate data for the fields
     */

    for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
	    continue;;
	iov[i].data.data = p;
	p += iov[i].data.length;
    }
    assert(iov[1].data.length == in.length);
    memcpy(iov[1].data.data, in.data, iov[1].data.length);

    assert(iov[3].data.length == in2.length);
    memcpy(iov[3].data.data, in2.data, iov[3].data.length);



    /*
     * Encrypt
     */

    ret = krb5_encrypt_iov_ivec(context, crypto, 7,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec");

    /*
     * Decrypt
     */

    ret = krb5_decrypt_iov_ivec(context, crypto, 7,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec");

    /*
     * Verify data
     */

    if (krb5_data_cmp(&iov[1].data, &in) != 0)
	krb5_errx(context, 1, "decrypted data 2.1 not same");

    if (krb5_data_cmp(&iov[3].data, &in2) != 0)
	krb5_errx(context, 1, "decrypted data 2.2 not same");

    /*
     * Free memory
     */

    free(base);

    krb5_crypto_destroy(context, crypto);

    krb5_free_keyblock_contents(context, &key);

    return 0;
}
예제 #4
0
static int
krb_enc_iov2(krb5_context context,
	     krb5_crypto crypto,
	     unsigned usage,
	     size_t cipher_len,
	     krb5_data *clear)
{
    krb5_crypto_iov iov[4];
    krb5_data decrypt;
    int ret;
    char *p, *q;
    size_t len, i;

    p = clear->data;
    len = clear->length;

    iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
    krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
    iov[0].data.data = emalloc(iov[0].data.length);

    iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
    iov[1].data.length = len;
    iov[1].data.data = emalloc(iov[1].data.length);
    memcpy(iov[1].data.data, p, iov[1].data.length);

    /* padding buffer */
    iov[2].flags = KRB5_CRYPTO_TYPE_PADDING;
    krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_PADDING, &iov[2].data.length);
    iov[2].data.data = emalloc(iov[2].data.length);

    iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER;
    krb5_crypto_length(context, crypto, iov[3].flags, &iov[3].data.length);
    iov[3].data.data = emalloc(iov[3].data.length);

    ret = krb5_encrypt_iov_ivec(context, crypto, usage,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    if (ret)
	errx(1, "encrypt iov failed: %d", ret);

    /* check len */
    for (i = 0, len = 0; i < sizeof(iov)/sizeof(iov[0]); i++)
	len += iov[i].data.length;
    if (len != cipher_len)
	errx(1, "cipher len wrong");

    /*
     * Plain decrypt
     */

    p = q = emalloc(len);
    for (i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
	memcpy(q, iov[i].data.data, iov[i].data.length);
	q += iov[i].data.length;
    }

    ret = krb5_decrypt(context, crypto, usage, p, len, &decrypt);
    if (ret)
	krb5_err(context, 1, ret, "krb5_decrypt");
    else
	krb5_data_free(&decrypt);

    free(p);

    /*
     * Now decrypt use iov
     */

    /* padding turn into data */
    p = q = emalloc(iov[1].data.length + iov[2].data.length);

    memcpy(q, iov[1].data.data, iov[1].data.length);
    q += iov[1].data.length;
    memcpy(q, iov[2].data.data, iov[2].data.length);

    free(iov[1].data.data);
    free(iov[2].data.data);

    iov[1].data.data = p;
    iov[1].data.length += iov[2].data.length;

    iov[2].flags = KRB5_CRYPTO_TYPE_EMPTY;
    iov[2].data.length = 0;

    ret = krb5_decrypt_iov_ivec(context, crypto, usage,
				iov, sizeof(iov)/sizeof(iov[0]), NULL);
    free(iov[0].data.data);
    free(iov[3].data.data);

    if (ret)
	krb5_err(context, 1, ret, "decrypt iov failed: %d", ret);

    if (clear->length != iov[1].data.length)
	errx(1, "length incorrect");

    p = clear->data;
    if (memcmp(iov[1].data.data, p, iov[1].data.length) != 0)
	errx(1, "iov[1] incorrect");

    free(iov[1].data.data);

    return 0;
}
예제 #5
0
파일: cfx.c 프로젝트: Henauxg/minix
OM_uint32
_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
		     gsskrb5_ctx ctx,
		     krb5_context context,
		     int conf_req_flag,
		     int *conf_state,
		     gss_iov_buffer_desc *iov,
		     int iov_count)
{
    OM_uint32 major_status, junk;
    gss_iov_buffer_desc *header, *trailer, *padding;
    size_t gsshsize, k5hsize;
    size_t gsstsize, k5tsize;
    size_t rrc = 0, ec = 0;
    int i;
    gss_cfx_wrap_token token;
    krb5_error_code ret;
    int32_t seq_number;
    unsigned usage;
    krb5_crypto_iov *data = NULL;

    header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
    if (header == NULL) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
    if (padding != NULL) {
	padding->buffer.length = 0;
    }

    trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);

    major_status = _gk_verify_buffers(minor_status, ctx, header, padding, trailer);
    if (major_status != GSS_S_COMPLETE) {
	    return major_status;
    }

    if (conf_req_flag) {
	size_t k5psize = 0;
	size_t k5pbase = 0;
	size_t k5bsize = 0;
	size_t size = 0;

	for (i = 0; i < iov_count; i++) {
	    switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
	    case GSS_IOV_BUFFER_TYPE_DATA:
		size += iov[i].buffer.length;
		break;
	    default:
		break;
	    }
	}

	size += sizeof(gss_cfx_wrap_token_desc);

	*minor_status = krb5_crypto_length(context, ctx->crypto,
					   KRB5_CRYPTO_TYPE_HEADER,
					   &k5hsize);
	if (*minor_status)
	    return GSS_S_FAILURE;

	*minor_status = krb5_crypto_length(context, ctx->crypto,
					   KRB5_CRYPTO_TYPE_TRAILER,
					   &k5tsize);
	if (*minor_status)
	    return GSS_S_FAILURE;

	*minor_status = krb5_crypto_length(context, ctx->crypto,
					   KRB5_CRYPTO_TYPE_PADDING,
					   &k5pbase);
	if (*minor_status)
	    return GSS_S_FAILURE;

	if (k5pbase > 1) {
	    k5psize = k5pbase - (size % k5pbase);
	} else {
	    k5psize = 0;
	}

	if (k5psize == 0 && IS_DCE_STYLE(ctx)) {
	    *minor_status = krb5_crypto_getblocksize(context, ctx->crypto,
						     &k5bsize);
	    if (*minor_status)
		return GSS_S_FAILURE;
	    ec = k5bsize;
	} else {
	    ec = k5psize;
	}

	gsshsize = sizeof(gss_cfx_wrap_token_desc) + k5hsize;
	gsstsize = sizeof(gss_cfx_wrap_token_desc) + ec + k5tsize;
    } else {
	if (IS_DCE_STYLE(ctx)) {
	    *minor_status = EINVAL;
	    return GSS_S_FAILURE;
	}

	k5hsize = 0;
	*minor_status = krb5_crypto_length(context, ctx->crypto,
					   KRB5_CRYPTO_TYPE_CHECKSUM,
					   &k5tsize);
	if (*minor_status)
	    return GSS_S_FAILURE;

	gsshsize = sizeof(gss_cfx_wrap_token_desc);
	gsstsize = k5tsize;
    }

    /*
     *
     */

    if (trailer == NULL) {
	rrc = gsstsize;
	if (IS_DCE_STYLE(ctx))
	    rrc -= ec;
	gsshsize += gsstsize;
	gsstsize = 0;
    } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
	major_status = _gk_allocate_buffer(minor_status, trailer, gsstsize);
	if (major_status)
	    goto failure;
    } else if (trailer->buffer.length < gsstsize) {
	*minor_status = KRB5_BAD_MSIZE;
	major_status = GSS_S_FAILURE;
	goto failure;
    } else
	trailer->buffer.length = gsstsize;

    /*
     *
     */

    if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
	major_status = _gk_allocate_buffer(minor_status, header, gsshsize);
	if (major_status != GSS_S_COMPLETE)
	    goto failure;
    } else if (header->buffer.length < gsshsize) {
	*minor_status = KRB5_BAD_MSIZE;
	major_status = GSS_S_FAILURE;
	goto failure;
    } else
	header->buffer.length = gsshsize;

    token = (gss_cfx_wrap_token)header->buffer.value;

    token->TOK_ID[0] = 0x05;
    token->TOK_ID[1] = 0x04;
    token->Flags     = 0;
    token->Filler    = 0xFF;

    if ((ctx->more_flags & LOCAL) == 0)
	token->Flags |= CFXSentByAcceptor;

    if (ctx->more_flags & ACCEPTOR_SUBKEY)
	token->Flags |= CFXAcceptorSubkey;

    if (ctx->more_flags & LOCAL)
	usage = KRB5_KU_USAGE_INITIATOR_SEAL;
    else
	usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;

    if (conf_req_flag) {
	/*
	 * In Wrap tokens with confidentiality, the EC field is
	 * used to encode the size (in bytes) of the random filler.
	 */
	token->Flags |= CFXSealed;
	token->EC[0] = (ec >> 8) & 0xFF;
	token->EC[1] = (ec >> 0) & 0xFF;

    } else {