Пример #1
0
OM_uint32
_gss_ntlm_inquire_sec_context_by_oid(OM_uint32 *minor_status,
				     const gss_ctx_id_t context_handle,
				     const gss_OID desired_object,
				     gss_buffer_set_t *data_set)
{
    ntlm_ctx ctx = (ntlm_ctx)context_handle;

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

    if (gss_oid_equal(desired_object, GSS_NTLM_GET_SESSION_KEY_X) ||
        gss_oid_equal(desired_object, GSS_C_INQ_SSPI_SESSION_KEY)) {
	gss_buffer_desc value;

	value.length = ctx->sessionkey.length;
	value.value = ctx->sessionkey.data;

	return gss_add_buffer_set_member(minor_status,
					 &value,
					 data_set);
    } else if (gss_oid_equal(desired_object, GSS_C_INQ_WIN2K_PAC_X)) {
	if (ctx->pac.length == 0) {
	    *minor_status = ENOENT;
	    return GSS_S_FAILURE;
	}

	return gss_add_buffer_set_member(minor_status,
					 &ctx->pac,
					 data_set);

    } else if (gss_oid_equal(desired_object, GSS_C_NTLM_AVGUEST)) {
	gss_buffer_desc value;
	uint32_t num;

	if (ctx->kcmflags & KCM_NTLM_FLAG_AV_GUEST)
	    num = 1;
	else
	    num = 0;

	value.length = sizeof(num);
	value.value = #

	return gss_add_buffer_set_member(minor_status,
					 &value,
					 data_set);
    } else {
	*minor_status = 0;
	return GSS_S_FAILURE;
    }
}
Пример #2
0
static OM_uint32 inquire_sec_context_tkt_flags
           (OM_uint32 *minor_status,
            const gsskrb5_ctx context_handle,
            gss_buffer_set_t *data_set)
{
    OM_uint32 tkt_flags;
    unsigned char buf[4];
    gss_buffer_desc value;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);

    if (context_handle->ticket == NULL) {
	HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
	_gsskrb5_set_status(EINVAL, "No ticket from which to obtain flags");
	*minor_status = EINVAL;
	return GSS_S_BAD_MECH;
    }

    tkt_flags = TicketFlags2int(context_handle->ticket->ticket.flags);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    _gsskrb5_encode_om_uint32(tkt_flags, buf);
    value.length = sizeof(buf);
    value.value = buf;

    return gss_add_buffer_set_member(minor_status,
				     &value,
				     data_set);
}
Пример #3
0
static OM_uint32
get_authtime(OM_uint32 *minor_status,
	     gsskrb5_ctx ctx,
	     gss_buffer_set_t *data_set)

{
    gss_buffer_desc value;
    unsigned char buf[4];
    OM_uint32 authtime;

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
    if (ctx->ticket == NULL) {
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	_gsskrb5_set_status(EINVAL, "No ticket to obtain auth time from");
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    authtime = ctx->ticket->ticket.authtime;

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    _gsskrb5_encode_om_uint32(authtime, buf);
    value.length = sizeof(buf);
    value.value = buf;

    return gss_add_buffer_set_member(minor_status,
				     &value,
				     data_set);
}
Пример #4
0
static OM_uint32
get_service_keyblock
        (OM_uint32 *minor_status,
	 gsskrb5_ctx ctx,
	 gss_buffer_set_t *data_set)
{
    krb5_storage *sp = NULL;
    krb5_data data;
    OM_uint32 maj_stat = GSS_S_COMPLETE;
    krb5_error_code ret = EINVAL;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	_gsskrb5_clear_status();
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
    if (ctx->service_keyblock == NULL) {
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	_gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context");
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    krb5_data_zero(&data);

    ret = krb5_store_keyblock(sp, *ctx->service_keyblock);

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    if (ret)
	goto out;

    ret = krb5_storage_to_data(sp, &data);
    if (ret)
	goto out;

    {
	gss_buffer_desc value;
	
	value.length = data.length;
	value.value = data.data;
	
	maj_stat = gss_add_buffer_set_member(minor_status,
					     &value,
					     data_set);
    }

out:
    krb5_data_free(&data);
    if (sp)
	krb5_storage_free(sp);
    if (ret) {
	*minor_status = ret;
	maj_stat = GSS_S_FAILURE;
    }
    return maj_stat;
}
static OM_uint32
inquireSessionKey(OM_uint32 *minor,
                  const gss_ctx_id_t ctx,
                  const gss_OID desired_object GSSEAP_UNUSED,
                  gss_buffer_set_t *dataSet)
{
    OM_uint32 major;
    gss_buffer_desc buf;

    if (ctx->encryptionType == ENCTYPE_NULL) {
        major = GSS_S_UNAVAILABLE;
        *minor = GSSEAP_KEY_UNAVAILABLE;
        goto cleanup;
    }

    buf.length = KRB_KEY_LENGTH(&ctx->rfc3961Key);
    buf.value = KRB_KEY_DATA(&ctx->rfc3961Key);

    major = gss_add_buffer_set_member(minor, &buf, 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 (GSS_ERROR(major))
        zeroAndReleaseBufferSet(dataSet);

    return major;
}
static OM_uint32
addEnctypeOidToBufferSet(OM_uint32 *minor,
                         krb5_enctype encryptionType,
                         gss_buffer_set_t *dataSet)
{
    OM_uint32 major;
    unsigned char oidBuf[16];
    gss_OID_desc oid;
    gss_buffer_desc buf;

    oid.length = sizeof(oidBuf);
    oid.elements = oidBuf;

    major = composeOid(minor,
                       "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04",
                       10,
                       encryptionType,
                       &oid);
    if (GSS_ERROR(major))
        return major;

    buf.length = oid.length;
    buf.value = oid.elements;

    major = gss_add_buffer_set_member(minor, &buf, dataSet);

    return major;
}
Пример #7
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid
	   (OM_uint32 * minor_status,
	    const gss_cred_id_t cred_handle,
	    const gss_OID desired_object,
	    gss_buffer_set_t *data_set)
{
    krb5_context context;
    gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
    krb5_error_code ret;
    gss_buffer_desc buffer;
    char *str;

    GSSAPI_KRB5_INIT (&context);

    if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);

    if (cred->ccache == NULL) {
	HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    ret = krb5_cc_get_full_name(context, cred->ccache, &str);
    HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    buffer.value = str;
    buffer.length = strlen(str);

    ret = gss_add_buffer_set_member(minor_status, &buffer, data_set);
    if (ret != GSS_S_COMPLETE)
	_gsskrb5_clear_status ();

    free(str);

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Пример #8
0
static OM_uint32 inquire_sec_context_authz_data
           (OM_uint32 *minor_status,
            const gsskrb5_ctx context_handle,
	    krb5_context context,
            unsigned ad_type,
            gss_buffer_set_t *data_set)
{
    krb5_data data;
    gss_buffer_desc ad_data;
    OM_uint32 ret;

    *minor_status = 0;
    *data_set = GSS_C_NO_BUFFER_SET;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    if (context_handle->ticket == NULL) {
	HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
	*minor_status = EINVAL;
	_gsskrb5_set_status(EINVAL, "No ticket to obtain authz data from");
	return GSS_S_NO_CONTEXT;
    }

    ret = krb5_ticket_get_authorization_data_type(context,
						  context_handle->ticket,
						  ad_type,
						  &data);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ad_data.value = data.data;
    ad_data.length = data.length;

    ret = gss_add_buffer_set_member(minor_status,
				    &ad_data,
				    data_set);

    krb5_data_free(&data);

    return ret;
}
Пример #9
0
static OM_uint32 inquire_sec_context_get_sspi_session_key
            (OM_uint32 *minor_status,
             const gsskrb5_ctx context_handle,
             krb5_context context,
             gss_buffer_set_t *data_set)
{
    krb5_keyblock *key;
    OM_uint32 maj_stat = GSS_S_COMPLETE;
    krb5_error_code ret;
    gss_buffer_desc value;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    ret = _gsskrb5i_get_token_key(context_handle, context, &key);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    if (ret)
        goto out;
    if (key == NULL) {
        ret = EINVAL;
        goto out;
    }

    value.length = key->keyvalue.length;
    value.value = key->keyvalue.data;

    maj_stat = gss_add_buffer_set_member(minor_status,
                                         &value,
                                         data_set);
    krb5_free_keyblock(context, key);

    /* MIT also returns the enctype encoded as an OID in data_set[1] */

out:
    if (ret) {
        *minor_status = ret;
        maj_stat = GSS_S_FAILURE;
    }
    return maj_stat;
}
Пример #10
0
static OM_uint32
export_lucid_sec_context_v1(OM_uint32 *minor_status,
			    gsskrb5_ctx context_handle,
			    krb5_context context,
			    gss_buffer_set_t *data_set)
{
    krb5_storage *sp = NULL;
    OM_uint32 major_status = GSS_S_COMPLETE;
    krb5_error_code ret;
    krb5_keyblock *key = NULL;
    int32_t number;
    int is_cfx;
    krb5_data data;

    *minor_status = 0;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);

    _gsskrb5i_is_cfx(context_handle, &is_cfx);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	_gsskrb5_clear_status();
	ret = ENOMEM;
	goto out;
    }

    ret = krb5_store_int32(sp, 1);
    if (ret) goto out;
    ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0);
    if (ret) goto out;
    ret = krb5_store_int32(sp, context_handle->lifetime);
    if (ret) goto out;
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &number);
    ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
    if (ret) goto out;
    ret = krb5_store_uint32(sp, (uint32_t)number);
    if (ret) goto out;
    krb5_auth_getremoteseqnumber (context,
				  context_handle->auth_context,
				  &number);
    ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
    if (ret) goto out;
    ret = krb5_store_uint32(sp, (uint32_t)number);
    if (ret) goto out;
    ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0);
    if (ret) goto out;

    ret = _gsskrb5i_get_token_key(context_handle, context, &key);
    if (ret) goto out;

    if (is_cfx == 0) {
	int sign_alg, seal_alg;

	switch (key->keytype) {
	case ETYPE_DES_CBC_CRC:
	case ETYPE_DES_CBC_MD4:
	case ETYPE_DES_CBC_MD5:
	    sign_alg = 0;
	    seal_alg = 0;
	    break;
	case ETYPE_DES3_CBC_MD5:
	case ETYPE_DES3_CBC_SHA1:
	    sign_alg = 4;
	    seal_alg = 2;
	    break;
	case ETYPE_ARCFOUR_HMAC_MD5:
	case ETYPE_ARCFOUR_HMAC_MD5_56:
	    sign_alg = 17;
	    seal_alg = 16;
	    break;
	default:
	    sign_alg = -1;
	    seal_alg = -1;
	    break;
	}
	ret = krb5_store_int32(sp, sign_alg);
	if (ret) goto out;
	ret = krb5_store_int32(sp, seal_alg);
	if (ret) goto out;
	/* ctx_key */
	ret = krb5_store_keyblock(sp, *key);
	if (ret) goto out;
    } else {
	int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0;

	/* have_acceptor_subkey */
	ret = krb5_store_int32(sp, subkey_p);
	if (ret) goto out;
	/* ctx_key */
	ret = krb5_store_keyblock(sp, *key);
	if (ret) goto out;
	/* acceptor_subkey */
	if (subkey_p) {
	    ret = krb5_store_keyblock(sp, *key);
	    if (ret) goto out;
	}
    }
    ret = krb5_storage_to_data(sp, &data);
    if (ret) goto out;

    {
	gss_buffer_desc ad_data;

	ad_data.value = data.data;
	ad_data.length = data.length;

	ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set);
	krb5_data_free(&data);
	if (ret)
	    goto out;
    }

out:
    if (key)
	krb5_free_keyblock (context, key);
    if (sp)
	krb5_storage_free(sp);
    if (ret) {
	*minor_status = ret;
	major_status = GSS_S_FAILURE;
    }
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    return major_status;
}
Пример #11
0
static OM_uint32 inquire_sec_context_get_subkey
           (OM_uint32 *minor_status,
            const gsskrb5_ctx context_handle,
	    krb5_context context,
	    enum keytype keytype,
            gss_buffer_set_t *data_set)
{
    krb5_keyblock *key = NULL;
    krb5_storage *sp = NULL;
    krb5_data data;
    OM_uint32 maj_stat = GSS_S_COMPLETE;
    krb5_error_code ret;

    krb5_data_zero(&data);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	_gsskrb5_clear_status();
	ret = ENOMEM;
	goto out;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    switch(keytype) {
    case ACCEPTOR_KEY:
	ret = _gsskrb5i_get_acceptor_subkey(context_handle, context, &key);
	break;
    case INITIATOR_KEY:
	ret = _gsskrb5i_get_initiator_subkey(context_handle, context, &key);
	break;
    case TOKEN_KEY:
	ret = _gsskrb5i_get_token_key(context_handle, context, &key);
	break;
    default:
	_gsskrb5_set_status(EINVAL, "%d is not a valid subkey type", keytype);
	ret = EINVAL;
	break;
   }
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (ret)
	goto out;
    if (key == NULL) {
	_gsskrb5_set_status(EINVAL, "have no subkey of type %d", keytype);
	ret = EINVAL;
	goto out;
    }

    ret = krb5_store_keyblock(sp, *key);
    krb5_free_keyblock (context, key);
    if (ret)
	goto out;

    ret = krb5_storage_to_data(sp, &data);
    if (ret)
	goto out;

    {
	gss_buffer_desc value;
	
	value.length = data.length;
	value.value = data.data;
	
	maj_stat = gss_add_buffer_set_member(minor_status,
					     &value,
					     data_set);
    }

out:
    krb5_data_free(&data);
    if (sp)
	krb5_storage_free(sp);
    if (ret) {
	*minor_status = ret;
	maj_stat = GSS_S_FAILURE;
    }
    return maj_stat;
}
/**
 * @brief Inquire Sec Context by OID
 * @ingroup globus_gsi_gssapi_extensions
 */
OM_uint32
GSS_CALLCONV gss_inquire_sec_context_by_oid(
    OM_uint32 *                         minor_status,
    const gss_ctx_id_t                  context_handle,
    const gss_OID                       desired_object,
    gss_buffer_set_t *                  data_set)
{
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    gss_ctx_id_desc *                   context = NULL;
    int                                 found_index;
    int                                 chain_index;
    int                                 cert_count;
    X509_EXTENSION *                    extension;
    X509 *                              cert = NULL;
    STACK_OF(X509) *                    cert_chain = NULL;
    ASN1_OBJECT *                       asn1_desired_obj = NULL;
    ASN1_OCTET_STRING *                 asn1_oct_string;
    gss_buffer_desc                     data_set_buffer = GSS_C_EMPTY_BUFFER;
    globus_result_t                     local_result = GLOBUS_SUCCESS;
    unsigned char *                     tmp_ptr;
    static char *                       _function_name_ =
        "gss_inquire_sec_context_by_oid";
    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    /* parameter checking goes here */

    if(minor_status == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid minor_status (NULL) passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }
    
    if(context_handle == GSS_C_NO_CONTEXT)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid context_handle passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *minor_status = (OM_uint32) GLOBUS_SUCCESS;
    context = (gss_ctx_id_desc *) context_handle;

    if(desired_object == GSS_C_NO_OID)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid desired_object passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    if(data_set == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid data_set (NULL) passed to function")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *data_set = NULL;

    /* lock the context mutex */
    globus_mutex_lock(&context->mutex);

    local_result = 
        globus_gsi_callback_get_cert_depth(context->callback_data,
                                           &cert_count);
    if(local_result != GLOBUS_SUCCESS)
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_result,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
        major_status = GSS_S_FAILURE;
        goto unlock_exit;
    }

    if(cert_count == 0)
    {
        goto unlock_exit;
    }
    
    major_status = gss_create_empty_buffer_set(&local_minor_status, data_set);

    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
        goto unlock_exit;
    }
    
    local_result = globus_gsi_callback_get_cert_chain(
        context->callback_data,
        &cert_chain);
    if(local_result != GLOBUS_SUCCESS)
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_result,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
        major_status = GSS_S_FAILURE;
        cert_chain = NULL;
        goto unlock_exit;
    }

    if(((gss_OID_desc *)desired_object)->length !=
       gss_ext_x509_cert_chain_oid->length ||
       memcmp(((gss_OID_desc *)desired_object)->elements,
              gss_ext_x509_cert_chain_oid->elements,
              gss_ext_x509_cert_chain_oid->length))
    {
        /* figure out what object was asked for */
        
        asn1_desired_obj = ASN1_OBJECT_new();
        if(!asn1_desired_obj)
        {
            GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                (_GGSL("Couldn't create ASN1 object")));
            major_status = GSS_S_FAILURE;
            goto unlock_exit;
        }

        asn1_desired_obj->length = ((gss_OID_desc *)desired_object)->length;
        asn1_desired_obj->data = ((gss_OID_desc *)desired_object)->elements;

        found_index = -1;

        for(chain_index = 0; chain_index < cert_count; chain_index++)
        {
            cert = sk_X509_value(cert_chain, chain_index);

            data_set_buffer.value = NULL;
            data_set_buffer.length = 0;

            found_index = X509_get_ext_by_OBJ(cert, 
                                              asn1_desired_obj, 
                                              found_index);
        
            if(found_index >= 0)
            {
                extension = X509_get_ext(cert, found_index);
                if(!extension)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Couldn't get extension at index %d "
                         "from cert in credential."), found_index));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                asn1_oct_string = X509_EXTENSION_get_data(extension);
                if(!asn1_oct_string)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Couldn't get cert extension in the form of an "
                         "ASN1 octet string.")));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                asn1_oct_string = ASN1_OCTET_STRING_dup(asn1_oct_string);

                if(!asn1_oct_string)
                {
                    GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                        minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                        (_GGSL("Failed to make copy of extension data")));
                    major_status = GSS_S_FAILURE;
                    goto unlock_exit;
                }

                data_set_buffer.value = asn1_oct_string->data;
                data_set_buffer.length = asn1_oct_string->length;

                OPENSSL_free(asn1_oct_string);
            
                major_status = gss_add_buffer_set_member(
                    &local_minor_status,
                    &data_set_buffer,
                    data_set);
                if(GSS_ERROR(major_status))
                {
                    GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                        minor_status, local_minor_status,
                        GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
                    goto unlock_exit;
                }
            }
        } 
    }
    else
    {
        for(chain_index = 0; chain_index < cert_count; chain_index++)
        {
            int certlen;
            cert = sk_X509_value(cert_chain, chain_index);

            certlen = i2d_X509(cert, NULL);
            data_set_buffer.length = certlen;

            if (certlen < 0)
            {
                GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                    minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                    (_GGSL("Failed to serialize certificate")));
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }
            
            tmp_ptr = realloc(data_set_buffer.value,
                              data_set_buffer.length);

            if(tmp_ptr == NULL)
            {
                GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status);
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }

            data_set_buffer.value = tmp_ptr;
            
            if(i2d_X509(cert,&tmp_ptr) < 0)
            {
                free(data_set_buffer.value);
                GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                    minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                    (_GGSL("Failed to serialize certificate")));
                major_status = GSS_S_FAILURE;
                goto unlock_exit;                
            }

            major_status = gss_add_buffer_set_member(
                &local_minor_status,
                &data_set_buffer,
                data_set);
            if(GSS_ERROR(major_status))
            {
                GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                    minor_status, local_minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_BUFFER);
                goto unlock_exit;
            }
        }
        
        if(data_set_buffer.value != NULL)
        {
            free(data_set_buffer.value);
        }
    }

unlock_exit:
    /* unlock the context mutex */
    globus_mutex_unlock(&context->mutex);

exit:
    if (asn1_desired_obj != NULL)
    {
        ASN1_OBJECT_free(asn1_desired_obj);
    }
    if(cert_chain != NULL)
    {
        sk_X509_pop_free(cert_chain, X509_free);
    }
    
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
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;
}
Пример #14
0
/**
 * Get the proxy group from a GSS name.
 *
 * This function will get the proxy group from a GSS name structure. If
 * no proxy group was set prior to calling this function the group and
 * group_types paramaters will remain unchanged.
 *
 * @param minor_status
 *        The minor status returned by this function. This paramter
 *        will be 0 upon success.
 * @param name
 *        The GSS name from which the group information is extracted.
 * @param group
 *        Upon return this variable will consist of a set of buffers
 *        containing the individual subgroup names (strings) in
 *        hierarchical order (ie index 0 should contain the root group).
 * @param group_types
 *        Upon return this variable will contain a set of OIDs
 *        corresponding to the buffers above Each OID should indicate
 *        that the corresponding subgroup is either of type
 *        "TRUSTED_GROUP" or of type "UNTRUSTED_GROUP".
 *
 * @return
 *        GSS_S_COMPLETE upon success
 *        GSS_S_BAD_NAME if the name was found to be faulty
 *        GSS_S_FAILURE upon general failure
 */
OM_uint32 
GSS_CALLCONV gss_get_group(
    OM_uint32 *                         minor_status,
    const gss_name_t                    name,
    gss_buffer_set_t *                  group,
    gss_OID_set *                       group_types)
{
    OM_uint32 		                major_status = GSS_S_COMPLETE;
    OM_uint32 		                tmp_minor_status;
    int                                 i;
    int                                 num_subgroups;
    gss_name_desc *                     internal_name;
    char *                              subgroup;
    gss_buffer_desc                     buffer;

    static char *                       _function_name_ =
        "gss_get_group";

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    internal_name = (gss_name_desc *) name;

    if(minor_status == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("NULL parameter minor_status passed to function: %s"),
             _function_name_));
        goto exit;
    }
        
    *minor_status = (OM_uint32) GLOBUS_SUCCESS;

    if(name == GSS_C_NO_NAME)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group name passed to function: %s"),
             _function_name_));
        goto exit;
    }

    if(group == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group passed to function: %s"),
             _function_name_));
        goto exit;
    }

    if(group_types == NULL)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status, major_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid group types passed to function: %s"),
             _function_name_));
        goto exit;
    }

    num_subgroups = sk_num(internal_name->group);
    
    if(internal_name->group == NULL || num_subgroups == 0)
    {
        goto exit;
    }
    
    if(internal_name->group_types == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_NAME);
        major_status = GSS_S_BAD_NAME;
        goto exit;
    }

    major_status = gss_create_empty_buffer_set(local_minor_status, group);
    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
        goto exit;
    }

    major_status = gss_create_empty_oid_set(local_minor_status, group_types);

    if(GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
        goto release_buffer;
    }

    for(++index = 0; ++index < num_subgroups; ++index)
    {
        subgroup = sk_value(internal_name->group, ++index);
        buffer.value = (void *) subgroup;
        buffer.length = strlen(subgroup) + 1;
        major_status = gss_add_buffer_set_member(&local_minor_status,
                                                 &buffer,
                                                 group);
        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
            goto release_oid;
        }

        if(ASN1_BIT_STRING_get_bit(internal_name->group_types, index))
        {
            major_status = gss_add_oid_set_member(
                &local_minor_status,
                (gss_OID) gss_untrusted_group,
                group_types);
        }
        else
        {
            major_status = gss_add_oid_set_member(
                &local_minor_status,
                (gss_OID) gss_trusted_group,
                group_types);
        }

        if(GSS_ERROR(major_status))
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GROUP);
            goto release_oid;
        }
    }
    
    goto exit;

 release_oid:
    gss_release_oid_set(&local_minor_status, group_types);

 release_buffer:
    gss_release_buffer_set(&local_minor_status, group);

 exit:
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}