// Copyright 2013-2015 Apcera Inc. All rights reserved. package gssapi /* #include OM_uint32 wrap_gss_get_mic(void *fp, OM_uint32 * minor_status, const gss_ctx_id_t context_handle, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token) { return ((OM_uint32(*) ( OM_uint32 *, const gss_ctx_id_t, gss_qop_t, const gss_buffer_t, gss_buffer_t) ) fp)( minor_status, context_handle, qop_req, message_buffer, message_token); } OM_uint32 wrap_gss_verify_mic(void *fp, OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state) { return ((OM_uint32(*) ( OM_uint32 *, const gss_ctx_id_t, const gss_buffer_t, const gss_buffer_t, gss_qop_t *) ) fp)( minor_status, context_handle, message_buffer, token_buffer, qop_state); } OM_uint32 wrap_gss_wrap(void *fp, OM_uint32 * minor_status, const gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int * conf_state, gss_buffer_t output_message_buffer) { return ((OM_uint32(*) ( OM_uint32 *, const gss_ctx_id_t, int, gss_qop_t, const gss_buffer_t, int *, gss_buffer_t) ) fp)( minor_status, context_handle, conf_req_flag, qop_req, input_message_buffer, conf_state, output_message_buffer); } OM_uint32 wrap_gss_unwrap(void *fp, OM_uint32 * minor_status, const gss_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int * conf_state, gss_qop_t * qop_state) { return ((OM_uint32(*) ( OM_uint32 *, const gss_ctx_id_t, const gss_buffer_t, gss_buffer_t, int *, gss_qop_t *) ) fp)( minor_status, context_handle, input_message_buffer, output_message_buffer, conf_state, qop_state); } */ import "C" // GetMIC implements gss_GetMIC API, as per https://tools.ietf.org/html/rfc2743#page-63. // messageToken must be .Release()-ed by the caller. func (ctx *CtxId) GetMIC(qopReq QOP, messageBuffer *Buffer) ( messageToken *Buffer, err error) { min := C.OM_uint32(0) token, err := ctx.MakeBuffer(allocGSSAPI) if err != nil { return nil, err } maj := C.wrap_gss_get_mic(ctx.Fp_gss_get_mic, &min, ctx.C_gss_ctx_id_t, C.gss_qop_t(qopReq), messageBuffer.C_gss_buffer_t, token.C_gss_buffer_t) err = ctx.stashLastStatus(maj, min) if err != nil { return nil, err } return token, nil } // VerifyMIC implements gss_VerifyMIC API, as per https://tools.ietf.org/html/rfc2743#page-64. func (ctx *CtxId) VerifyMIC(messageBuffer *Buffer, tokenBuffer *Buffer) ( qopState QOP, err error) { min := C.OM_uint32(0) qop := C.gss_qop_t(0) maj := C.wrap_gss_verify_mic(ctx.Fp_gss_verify_mic, &min, ctx.C_gss_ctx_id_t, messageBuffer.C_gss_buffer_t, tokenBuffer.C_gss_buffer_t, &qop) err = ctx.stashLastStatus(maj, min) if err != nil { return 0, err } return QOP(qop), nil } // Wrap implements gss_wrap API, as per https://tools.ietf.org/html/rfc2743#page-65. // outputMessageBuffer must be .Release()-ed by the caller func (ctx *CtxId) Wrap( confReq bool, qopReq QOP, inputMessageBuffer *Buffer) ( confState bool, outputMessageBuffer *Buffer, err error) { min := C.OM_uint32(0) encrypt := C.int(0) if confReq { encrypt = 1 } outputMessageBuffer, err = ctx.MakeBuffer(allocGSSAPI) if err != nil { return false, nil, err } encrypted := C.int(0) maj := C.wrap_gss_wrap(ctx.Fp_gss_wrap, &min, ctx.C_gss_ctx_id_t, encrypt, C.gss_qop_t(qopReq), inputMessageBuffer.C_gss_buffer_t, &encrypted, outputMessageBuffer.C_gss_buffer_t) err = ctx.stashLastStatus(maj, min) if err != nil { return false, nil, err } return encrypted != 0, outputMessageBuffer, nil } // Unwrap implements gss_unwrap API, as per https://tools.ietf.org/html/rfc2743#page-66. // outputMessageBuffer must be .Release()-ed by the caller func (ctx *CtxId) Unwrap( inputMessageBuffer *Buffer) ( outputMessageBuffer *Buffer, confState bool, qopState QOP, err error) { min := C.OM_uint32(0) outputMessageBuffer, err = ctx.MakeBuffer(allocGSSAPI) if err != nil { return nil, false, 0, err } encrypted := C.int(0) qop := C.gss_qop_t(0) maj := C.wrap_gss_unwrap(ctx.Fp_gss_unwrap, &min, ctx.C_gss_ctx_id_t, inputMessageBuffer.C_gss_buffer_t, outputMessageBuffer.C_gss_buffer_t, &encrypted, &qop) err = ctx.stashLastStatus(maj, min) if err != nil { return nil, false, 0, err } return outputMessageBuffer, encrypted != 0, QOP(qop), nil }