Пример #1
0
/*
 * AEAD unwrap for a single piece of associated data, for compatibility
 * with MIT and as specified by draft-howard-gssapi-aead-00.txt.
 *
 * @ingroup gssapi
 */
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_unwrap_aead(OM_uint32 *minor_status,
		gss_ctx_id_t context_handle,
		gss_buffer_t input_message_buffer,
		gss_buffer_t input_assoc_buffer,
		gss_buffer_t output_payload_buffer,
		int *conf_state,
		gss_qop_t *qop_state)
{
    OM_uint32 major_status, tmp;
    gss_iov_buffer_desc iov[3];

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

    iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
    iov[0].buffer = *input_message_buffer;

    iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
    if (input_assoc_buffer)
	iov[1].buffer = *input_assoc_buffer;

    iov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;

    major_status = gss_unwrap_iov(minor_status, context_handle, conf_state,
				  qop_state, iov, 3);
    if (GSS_ERROR(major_status))
	gss_release_iov_buffer(&tmp, &iov[2], 1);
    else
	*output_payload_buffer = iov[2].buffer;

    return major_status;
}
Пример #2
0
OM_uint32 GSSAPI_CALLCONV
_gss_spnego_unwrap_iov(OM_uint32 *minor_status,
		       gss_ctx_id_t context_handle,
		       int *conf_state,
		       gss_qop_t *qop_state,
		       gss_iov_buffer_desc *iov,
		       int iov_count)
{
    gssspnego_ctx ctx = (gssspnego_ctx)context_handle;

    *minor_status = 0;

    if (ctx == NULL || ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
	return GSS_S_NO_CONTEXT;

    return gss_unwrap_iov(minor_status,
			  ctx->negotiated_ctx_id,
			  conf_state, qop_state,
			  iov, iov_count);
}
Пример #3
0
NTSTATUS gssapi_unseal_packet(gss_ctx_id_t gssapi_context,
			      const gss_OID mech,
			      bool hdr_signing,
			      uint8_t *data, size_t length,
			      const uint8_t *whole_pdu, size_t pdu_length,
			      const DATA_BLOB *sig)
{
	OM_uint32 maj_stat, min_stat;
	gss_iov_buffer_desc iov[4];
	gss_qop_t qop_state;
	int sealed = 0;
	const uint8_t *pre_sign_ptr = NULL;
	size_t pre_sign_len = 0;
	const uint8_t *post_sign_ptr = NULL;
	size_t post_sign_len = 0;

	if (hdr_signing) {
		const uint8_t *de = data + length;
		const uint8_t *we = whole_pdu + pdu_length;

		if (data < whole_pdu) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		if (de > we) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		pre_sign_len = data - whole_pdu;
		if (pre_sign_len > 0) {
			pre_sign_ptr = whole_pdu;
		}
		post_sign_len = we - de;
		if (post_sign_len > 0) {
			post_sign_ptr = de;
		}
	}

	dump_data_pw("gssapi_unseal_packet: sig\n", sig->data, sig->length);
	dump_data_pw("gssapi_unseal_packet: sealed\n", data, length);

	iov[0].type          = GSS_IOV_BUFFER_TYPE_HEADER;
	iov[0].buffer.length = sig->length;
	iov[0].buffer.value  = sig->data;

	if (pre_sign_ptr != NULL) {
		iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
		iov[1].buffer.length = pre_sign_len;
		iov[1].buffer.value = discard_const(pre_sign_ptr);
	} else {
		iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY;
		iov[1].buffer.length = 0;
		iov[1].buffer.value = NULL;
	}

	/* data is encrypted in place, which is ok */
	iov[2].type          = GSS_IOV_BUFFER_TYPE_DATA;
	iov[2].buffer.length = length;
	iov[2].buffer.value  = data;

	if (post_sign_ptr != NULL) {
		iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
		iov[3].buffer.length = post_sign_len;
		iov[3].buffer.value = discard_const(post_sign_ptr);
	} else {
		iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY;
		iov[3].buffer.length = 0;
		iov[3].buffer.value = NULL;
	}

	maj_stat = gss_unwrap_iov(&min_stat,
				  gssapi_context,
				  &sealed,
				  &qop_state,
				  iov, ARRAY_SIZE(iov));
	if (GSS_ERROR(maj_stat)) {
		char *error_string = gssapi_error_string(NULL,
							 maj_stat,
							 min_stat,
							 mech);
		DEBUG(1, ("gss_unwrap_iov failed: %s\n", error_string));
		talloc_free(error_string);

		return NT_STATUS_ACCESS_DENIED;
	}

	if (sealed == 0) {
		DEBUG(0, ("gss_unwrap_iov says data was not sealed!\n"));
		return NT_STATUS_ACCESS_DENIED;
	}

	DEBUG(10, ("Unsealed %d bytes, with %d bytes header/signature.\n",
		   (int)iov[2].buffer.length, (int)iov[0].buffer.length));

	return NT_STATUS_OK;
}
Пример #4
0
static int
HandleOP(UnwrapExt)
{
    OM_uint32 maj_stat, min_stat;
    int32_t hContext, flags, bflags;
    krb5_data token, header, trailer;
    gss_ctx_id_t ctx;
    gss_iov_buffer_desc iov[3];
    int conf_state, iov_len;
    gss_qop_t qop_state;

    ret32(c, hContext);
    ret32(c, flags);
    ret32(c, bflags);
    retdata(c, header);
    retdata(c, token);
    retdata(c, trailer);

    iov_len = sizeof(iov)/sizeof(iov[0]);

    if (bflags & WRAP_EXP_ONLY_HEADER)
	iov_len -= 1; /* skip trailer and padding, aka dce-style */

    ctx = find_handle(c->handles, hContext, handle_context);
    if (ctx == NULL)
	errx(1, "unwrap: reference to unknown context");

    if (header.length != 0) {
	iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
	iov[0].buffer.length = header.length;
	iov[0].buffer.value = header.data;
    } else {
	iov[0].type = GSS_IOV_BUFFER_TYPE_EMPTY;
    }
    iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
    iov[1].buffer.length = token.length;
    iov[1].buffer.value = token.data;

    if (trailer.length != 0) {
	iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
	iov[2].buffer.length = trailer.length;
	iov[2].buffer.value = trailer.data;
    } else {
	iov[2].type = GSS_IOV_BUFFER_TYPE_EMPTY;
    }

    maj_stat = gss_unwrap_iov(&min_stat, ctx, &conf_state, &qop_state,
			      iov, iov_len);

    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_unwrap failed: %d/%d", maj_stat, min_stat);

    if (maj_stat == GSS_S_COMPLETE) {
	token.data = iov[1].buffer.value;
	token.length = iov[1].buffer.length;
    } else {
	token.data = NULL;
	token.length = 0;
    }
    put32(c, 0); /* XXX fix gsm_error */
    putdata(c, token);

    return 0;
}
Пример #5
0
int authenticate_gss_client_unwrap_iov(gss_client_state *state, const char *challenge)
{
        OM_uint32 maj_stat;
        OM_uint32 min_stat;
        int conf_state = 1;
        OM_uint32 qop_state = 0;
        int ret = AUTH_GSS_COMPLETE;
        int iov_count = 3;
        gss_iov_buffer_desc iov[iov_count];
        unsigned char * data = NULL;
        size_t len = 0;
        unsigned int token_len = 0;

        // Always clear out the old response
        if (state->response != NULL)
        {
            free(state->response);
            state->response = NULL;
            state->responseConf = 0;
        }

        // If there is a challenge (data from the server) we need to give it to GSS
        if (challenge && *challenge)
        {
            data = base64_decode(challenge, &len);
        }

        if (!data || len == 0)
        {
            // nothing to do, return
            data = (unsigned char *)malloc(1);
            data[0] = 0;
            state->response = (char*)data;
            return AUTH_GSS_COMPLETE;
        }

        memcpy(&token_len, data, sizeof(unsigned int));

        if (len-4-token_len < 0)
        {
            PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))","Data length error in response", -1));
            free(data);
            return AUTH_GSS_ERROR;
        }

        iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
        iov[0].buffer.value = data+4;
        iov[0].buffer.length = token_len;

        iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
        iov[1].buffer.value = data+4+token_len;
		iov[1].buffer.length = len-4-token_len;

        iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
        iov[2].buffer.value = "";
        iov[2].buffer.length = 0;

        maj_stat = gss_unwrap_iov(&min_stat, state->context, &conf_state, &qop_state, iov, iov_count);

        if (maj_stat != GSS_S_COMPLETE)
        {
            set_gss_error(maj_stat, min_stat);
            ret = AUTH_GSS_ERROR;
        }
        else
        {
            ret = AUTH_GSS_COMPLETE;

            // Grab the client response
            state->responseConf = conf_state;
            state->response = base64_encode((const unsigned char *)iov[1].buffer.value, iov[1].buffer.length);
        }

        free(data);
        return ret;
}
Пример #6
0
static void
wrapunwrap_iov(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
{
    krb5_data token, header, trailer;
    OM_uint32 min_stat, maj_stat;
    gss_qop_t qop_state;
    int conf_state, conf_state2;
    gss_iov_buffer_desc iov[6];
    unsigned char *p;
    int iov_len;
    char header_data[9] = "ABCheader";
    char trailer_data[10] = "trailerXYZ";

    char token_data[16] = "0123456789abcdef";

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

    if (flags & USE_SIGN_ONLY) {
	header.data = header_data;
	header.length = 9;
	trailer.data = trailer_data;
	trailer.length = 10;
    } else {
	header.data = NULL;
	header.length = 0;
	trailer.data = NULL;
	trailer.length = 0;
    }

    token.data = token_data;
    token.length = 16;

    iov_len = sizeof(iov)/sizeof(iov[0]);

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

    iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;

    if (header.length != 0) {
	iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
	iov[1].buffer.length = header.length;
	iov[1].buffer.value = header.data;
    } else {
	iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY;
	iov[1].buffer.length = 0;
	iov[1].buffer.value = NULL;
    }
    iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
    iov[2].buffer.length = token.length;
    iov[2].buffer.value = token.data;
    if (trailer.length != 0) {
	iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
	iov[3].buffer.length = trailer.length;
	iov[3].buffer.value = trailer.data;
    } else {
	iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY;
	iov[3].buffer.length = 0;
	iov[3].buffer.value = NULL;
    }
    if (dce_style_flag) {
	iov[4].type = GSS_IOV_BUFFER_TYPE_EMPTY;
    } else {
	iov[4].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
    }
    iov[4].buffer.length = 0;
    iov[4].buffer.value = 0;
    if (dce_style_flag) {
	iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
    } else if (flags & USE_HEADER_ONLY) {
	iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
    } else {
	iov[5].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
    }
    iov[5].buffer.length = 0;
    iov[5].buffer.value = 0;

    maj_stat = gss_wrap_iov(&min_stat, cctx, dce_style_flag || flags & USE_CONF, 0, &conf_state,
			    iov, iov_len);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_wrap_iov failed");

    token.length =
	iov[0].buffer.length +
	iov[1].buffer.length +
	iov[2].buffer.length +
	iov[3].buffer.length +
	iov[4].buffer.length +
	iov[5].buffer.length;
    token.data = emalloc(token.length);

    p = token.data;
    memcpy(p, iov[0].buffer.value, iov[0].buffer.length);
    p += iov[0].buffer.length;
    memcpy(p, iov[1].buffer.value, iov[1].buffer.length);
    p += iov[1].buffer.length;
    memcpy(p, iov[2].buffer.value, iov[2].buffer.length);
    p += iov[2].buffer.length;
    memcpy(p, iov[3].buffer.value, iov[3].buffer.length);
    p += iov[3].buffer.length;
    memcpy(p, iov[4].buffer.value, iov[4].buffer.length);
    p += iov[4].buffer.length;
    memcpy(p, iov[5].buffer.value, iov[5].buffer.length);
    p += iov[5].buffer.length;

    assert(p - ((unsigned char *)token.data) == token.length);

    if ((flags & (USE_SIGN_ONLY|FORCE_IOV)) == 0) {
	gss_buffer_desc input, output;

	input.value = token.data;
	input.length = token.length;

	maj_stat = gss_unwrap(&min_stat, sctx, &input,
			      &output, &conf_state2, &qop_state);

	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_unwrap from gss_wrap_iov failed: %s",
		 gssapi_err(maj_stat, min_stat, mechoid));

	gss_release_buffer(&min_stat, &output);
    } else {
	maj_stat = gss_unwrap_iov(&min_stat, sctx, &conf_state2, &qop_state,
				  iov, iov_len);

	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_unwrap_iov failed: %x %s", flags,
		 gssapi_err(maj_stat, min_stat, mechoid));

    }
    if (conf_state2 != conf_state)
	errx(1, "conf state wrong for iov: %x", flags);


    free(token.data);
}