gss_aeap.c revision 226031
11573Srgrimes/* 21573Srgrimes * AEAD support 31573Srgrimes */ 41573Srgrimes 51573Srgrimes#include "mech_locl.h" 61573Srgrimes 71573Srgrimes/** 81573Srgrimes * Encrypts or sign the data. 91573Srgrimes * 101573Srgrimes * This is a more complicated version of gss_wrap(), it allows the 111573Srgrimes * caller to use AEAD data (signed header/trailer) and allow greater 121573Srgrimes * controll over where the encrypted data is placed. 131573Srgrimes * 141573Srgrimes * The maximum packet size is gss_context_stream_sizes.max_msg_size. 151573Srgrimes * 16148834Sstefanf * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode: 171573Srgrimes * 181573Srgrimes * - HEADER (of size gss_context_stream_sizes.header) 191573Srgrimes * { DATA or SIGN_ONLY } (optional, zero or more) 201573Srgrimes * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) 211573Srgrimes * TRAILER (of size gss_context_stream_sizes.trailer) 221573Srgrimes * 231573Srgrimes * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the 241573Srgrimes * DATA elements is padded to a block bountry and header is of at 251573Srgrimes * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer. 261573Srgrimes * 271573Srgrimes * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large. 281573Srgrimes * 291573Srgrimes * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER 301573Srgrimes * 311573Srgrimes * When used in conf_req_flag=0, 321573Srgrimes * 33148834Sstefanf * - HEADER (of size gss_context_stream_sizes.header) 3484260Sobrien * { DATA or SIGN_ONLY } (optional, zero or more) 351573Srgrimes * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted) 361573Srgrimes * TRAILER (of size gss_context_stream_sizes.trailer) 371573Srgrimes * 381573Srgrimes * 391573Srgrimes * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or 401573Srgrimes * gss_context_query_attributes(). 4184260Sobrien * 421573Srgrimes * @ingroup gssapi 431573Srgrimes */ 441573Srgrimes 4584260Sobrien 461573SrgrimesGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 471573Srgrimesgss_wrap_iov(OM_uint32 * minor_status, 4884260Sobrien gss_ctx_id_t context_handle, 4984260Sobrien int conf_req_flag, 5084260Sobrien gss_qop_t qop_req, 5184260Sobrien int * conf_state, 5284260Sobrien gss_iov_buffer_desc *iov, 5384260Sobrien int iov_count) 5484260Sobrien{ 551573Srgrimes struct _gss_context *ctx = (struct _gss_context *) context_handle; 561573Srgrimes gssapi_mech_interface m; 5784260Sobrien 5884260Sobrien if (minor_status) 5984260Sobrien *minor_status = 0; 601573Srgrimes if (conf_state) 611573Srgrimes *conf_state = 0; 621573Srgrimes if (ctx == NULL) 631573Srgrimes return GSS_S_NO_CONTEXT; 641573Srgrimes if (iov == NULL && iov_count != 0) 65148834Sstefanf return GSS_S_CALL_INACCESSIBLE_READ; 6684260Sobrien 6784260Sobrien m = ctx->gc_mech; 68278411Sbapt 691573Srgrimes if (m->gm_wrap_iov == NULL) 7084260Sobrien return GSS_S_UNAVAILABLE; 7184260Sobrien 7284260Sobrien return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx, 7384260Sobrien conf_req_flag, qop_req, conf_state, 74148834Sstefanf iov, iov_count); 7584260Sobrien} 761573Srgrimes 771573Srgrimes/** 78 * Decrypt or verifies the signature on the data. 79 * 80 * 81 * @ingroup gssapi 82 */ 83 84GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 85gss_unwrap_iov(OM_uint32 *minor_status, 86 gss_ctx_id_t context_handle, 87 int *conf_state, 88 gss_qop_t *qop_state, 89 gss_iov_buffer_desc *iov, 90 int iov_count) 91{ 92 struct _gss_context *ctx = (struct _gss_context *) context_handle; 93 gssapi_mech_interface m; 94 95 if (minor_status) 96 *minor_status = 0; 97 if (conf_state) 98 *conf_state = 0; 99 if (qop_state) 100 *qop_state = 0; 101 if (ctx == NULL) 102 return GSS_S_NO_CONTEXT; 103 if (iov == NULL && iov_count != 0) 104 return GSS_S_CALL_INACCESSIBLE_READ; 105 106 m = ctx->gc_mech; 107 108 if (m->gm_unwrap_iov == NULL) 109 return GSS_S_UNAVAILABLE; 110 111 return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx, 112 conf_state, qop_state, 113 iov, iov_count); 114} 115 116/** 117 * Update the length fields in iov buffer for the types: 118 * - GSS_IOV_BUFFER_TYPE_HEADER 119 * - GSS_IOV_BUFFER_TYPE_PADDING 120 * - GSS_IOV_BUFFER_TYPE_TRAILER 121 * 122 * Consider using gss_context_query_attributes() to fetch the data instead. 123 * 124 * @ingroup gssapi 125 */ 126 127GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 128gss_wrap_iov_length(OM_uint32 * minor_status, 129 gss_ctx_id_t context_handle, 130 int conf_req_flag, 131 gss_qop_t qop_req, 132 int *conf_state, 133 gss_iov_buffer_desc *iov, 134 int iov_count) 135{ 136 struct _gss_context *ctx = (struct _gss_context *) context_handle; 137 gssapi_mech_interface m; 138 139 if (minor_status) 140 *minor_status = 0; 141 if (conf_state) 142 *conf_state = 0; 143 if (ctx == NULL) 144 return GSS_S_NO_CONTEXT; 145 if (iov == NULL && iov_count != 0) 146 return GSS_S_CALL_INACCESSIBLE_READ; 147 148 m = ctx->gc_mech; 149 150 if (m->gm_wrap_iov_length == NULL) 151 return GSS_S_UNAVAILABLE; 152 153 return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx, 154 conf_req_flag, qop_req, conf_state, 155 iov, iov_count); 156} 157 158/** 159 * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by 160 * looking at the GSS_IOV_BUFFER_FLAG_ALLOCATED flag. 161 * 162 * @ingroup gssapi 163 */ 164 165GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 166gss_release_iov_buffer(OM_uint32 *minor_status, 167 gss_iov_buffer_desc *iov, 168 int iov_count) 169{ 170 OM_uint32 junk; 171 int i; 172 173 if (minor_status) 174 *minor_status = 0; 175 if (iov == NULL && iov_count != 0) 176 return GSS_S_CALL_INACCESSIBLE_READ; 177 178 for (i = 0; i < iov_count; i++) { 179 if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0) 180 continue; 181 gss_release_buffer(&junk, &iov[i].buffer); 182 iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED; 183 } 184 return GSS_S_COMPLETE; 185} 186 187/** 188 * Query the context for parameters. 189 * 190 * SSPI equivalent if this function is QueryContextAttributes. 191 * 192 * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes. 193 * 194 * @ingroup gssapi 195 */ 196 197gss_OID_desc GSSAPI_LIB_FUNCTION __gss_c_attr_stream_sizes_oid_desc = 198 {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")}; 199 200GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 201gss_context_query_attributes(OM_uint32 *minor_status, 202 const gss_ctx_id_t context_handle, 203 const gss_OID attribute, 204 void *data, 205 size_t len) 206{ 207 if (minor_status) 208 *minor_status = 0; 209 210 if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) { 211 memset(data, 0, len); 212 return GSS_S_COMPLETE; 213 } 214 215 return GSS_S_FAILURE; 216} 217