LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/gssapi/mech - gss_aeap.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 38 122 31.1 %
Date: 2023-11-21 12:31:41 Functions: 3 7 42.9 %

          Line data    Source code
       1             : /*
       2             :  * AEAD support
       3             :  */
       4             : 
       5             : #include "mech_locl.h"
       6             : 
       7             : /**
       8             :  * Encrypts or sign the data.
       9             :  *
      10             :  * This is a more complicated version of gss_wrap(), it allows the
      11             :  * caller to use AEAD data (signed header/trailer) and allow greater
      12             :  * controll over where the encrypted data is placed.
      13             :  *
      14             :  * The maximum packet size is gss_context_stream_sizes.max_msg_size.
      15             :  *
      16             :  * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:
      17             :  *
      18             :  * - HEADER (of size gss_context_stream_sizes.header)
      19             :  *   { DATA or SIGN_ONLY } (optional, zero or more)
      20             :  *   PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
      21             :  *   TRAILER (of size gss_context_stream_sizes.trailer)
      22             :  *
      23             :  * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
      24             :  *   DATA elements is padded to a block bountry and header is of at
      25             :  *   least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.
      26             :  *
      27             :  * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.
      28             :  *
      29             :  * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
      30             :  *
      31             :  * When used in conf_req_flag=0,
      32             :  *
      33             :  * - HEADER (of size gss_context_stream_sizes.header)
      34             :  *   { DATA or SIGN_ONLY } (optional, zero or more)
      35             :  *   PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
      36             :  *   TRAILER (of size gss_context_stream_sizes.trailer)
      37             :  *
      38             :  *
      39             :  * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
      40             :  * gss_context_query_attributes().
      41             :  *
      42             :  * @ingroup gssapi
      43             :  */
      44             : 
      45             : 
      46             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
      47     1180969 : gss_wrap_iov(OM_uint32 * minor_status,
      48             :              gss_ctx_id_t  context_handle,
      49             :              int conf_req_flag,
      50             :              gss_qop_t qop_req,
      51             :              int * conf_state,
      52             :              gss_iov_buffer_desc *iov,
      53             :              int iov_count)
      54             : {
      55     1180969 :         struct _gss_context *ctx = (struct _gss_context *) context_handle;
      56        1313 :         gssapi_mech_interface m;
      57             : 
      58     1180969 :         if (minor_status)
      59     1180969 :             *minor_status = 0;
      60     1180969 :         if (conf_state)
      61     1180969 :             *conf_state = 0;
      62     1180969 :         if (ctx == NULL)
      63           0 :             return GSS_S_NO_CONTEXT;
      64     1180969 :         if (iov == NULL && iov_count != 0)
      65           0 :             return GSS_S_CALL_INACCESSIBLE_READ;
      66             : 
      67     1180969 :         m = ctx->gc_mech;
      68             : 
      69     1180969 :         if (m->gm_wrap_iov == NULL)
      70           0 :             return GSS_S_UNAVAILABLE;
      71             : 
      72     1180969 :         return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx,
      73             :                                 conf_req_flag, qop_req, conf_state,
      74             :                                 iov, iov_count);
      75             : }
      76             : 
      77             : /**
      78             :  * Decrypt or verifies the signature on the data.
      79             :  *
      80             :  *
      81             :  * @ingroup gssapi
      82             :  */
      83             : 
      84             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
      85      441245 : gss_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      441245 :         struct _gss_context *ctx = (struct _gss_context *) context_handle;
      93        1312 :         gssapi_mech_interface m;
      94             : 
      95      441245 :         if (minor_status)
      96      441245 :             *minor_status = 0;
      97      441245 :         if (conf_state)
      98      441245 :             *conf_state = 0;
      99      441245 :         if (qop_state)
     100      441245 :             *qop_state = 0;
     101      441245 :         if (ctx == NULL)
     102           0 :             return GSS_S_NO_CONTEXT;
     103      441245 :         if (iov == NULL && iov_count != 0)
     104           0 :             return GSS_S_CALL_INACCESSIBLE_READ;
     105             : 
     106      441245 :         m = ctx->gc_mech;
     107             : 
     108      441245 :         if (m->gm_unwrap_iov == NULL)
     109           0 :             return GSS_S_UNAVAILABLE;
     110             : 
     111      441245 :         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             : 
     127             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
     128       15759 : gss_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       15759 :         struct _gss_context *ctx = (struct _gss_context *) context_handle;
     137         184 :         gssapi_mech_interface m;
     138             : 
     139       15759 :         if (minor_status)
     140       15759 :             *minor_status = 0;
     141       15759 :         if (conf_state)
     142       15759 :             *conf_state = 0;
     143       15759 :         if (ctx == NULL)
     144           0 :             return GSS_S_NO_CONTEXT;
     145       15759 :         if (iov == NULL && iov_count != 0)
     146           0 :             return GSS_S_CALL_INACCESSIBLE_READ;
     147             : 
     148       15759 :         m = ctx->gc_mech;
     149             : 
     150       15759 :         if (m->gm_wrap_iov_length == NULL)
     151           0 :             return GSS_S_UNAVAILABLE;
     152             : 
     153       15759 :         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             : 
     165             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
     166           0 : gss_release_iov_buffer(OM_uint32 *minor_status,
     167             :                        gss_iov_buffer_desc *iov,
     168             :                        int iov_count)
     169             : {
     170           0 :     OM_uint32 junk;
     171           0 :     int i;
     172             : 
     173           0 :     if (minor_status)
     174           0 :         *minor_status = 0;
     175           0 :     if (iov == NULL && iov_count != 0)
     176           0 :         return GSS_S_CALL_INACCESSIBLE_READ;
     177             : 
     178           0 :     for (i = 0; i < iov_count; i++) {
     179           0 :         if ((iov[i].type & GSS_IOV_BUFFER_FLAG_ALLOCATED) == 0)
     180           0 :             continue;
     181           0 :         gss_release_buffer(&junk, &iov[i].buffer);
     182           0 :         iov[i].type &= ~GSS_IOV_BUFFER_FLAG_ALLOCATED;
     183             :     }
     184           0 :     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             : 
     197             : gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_attr_stream_sizes_oid_desc =
     198             :     {10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};
     199             : 
     200             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
     201           0 : gss_context_query_attributes(OM_uint32 *minor_status,
     202             :                              gss_const_ctx_id_t context_handle,
     203             :                              const gss_OID attribute,
     204             :                              void *data,
     205             :                              size_t len)
     206             : {
     207           0 :     if (minor_status)
     208           0 :         *minor_status = 0;
     209             : 
     210           0 :     if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) {
     211           0 :         memset(data, 0, len);
     212           0 :         return GSS_S_COMPLETE;
     213             :     }
     214             : 
     215           0 :     return GSS_S_FAILURE;
     216             : }
     217             : 
     218             : /*
     219             :  * AEAD wrap API for a single piece of associated data, for compatibility
     220             :  * with MIT and as specified by draft-howard-gssapi-aead-00.txt.
     221             :  *
     222             :  * @ingroup gssapi
     223             :  */
     224             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
     225           0 : gss_wrap_aead(OM_uint32 *minor_status,
     226             :               gss_ctx_id_t context_handle,
     227             :               int conf_req_flag,
     228             :               gss_qop_t qop_req,
     229             :               gss_buffer_t input_assoc_buffer,
     230             :               gss_buffer_t input_payload_buffer,
     231             :               int *conf_state,
     232             :               gss_buffer_t output_message_buffer)
     233             : {
     234           0 :     OM_uint32 major_status, tmp, flags = 0;
     235           0 :     gss_iov_buffer_desc iov[5];
     236           0 :     size_t i;
     237           0 :     unsigned char *p;
     238             : 
     239           0 :     memset(iov, 0, sizeof(iov));
     240             : 
     241           0 :     iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
     242             : 
     243           0 :     iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
     244           0 :     if (input_assoc_buffer)
     245           0 :         iov[1].buffer = *input_assoc_buffer;
     246             : 
     247           0 :     iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
     248           0 :     if (input_payload_buffer)
     249           0 :         iov[2].buffer.length = input_payload_buffer->length;
     250             : 
     251           0 :     gss_inquire_context(minor_status, context_handle, NULL, NULL,
     252             :                         NULL, NULL, &flags, NULL, NULL);
     253             : 
     254             :     /* krb5 mech rejects padding/trailer if DCE-style is set */
     255           0 :     iov[3].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY
     256           0 :                                             : GSS_IOV_BUFFER_TYPE_PADDING;
     257           0 :     iov[4].type = (flags & GSS_C_DCE_STYLE) ? GSS_IOV_BUFFER_TYPE_EMPTY
     258           0 :                                             : GSS_IOV_BUFFER_TYPE_TRAILER;
     259             : 
     260           0 :     major_status = gss_wrap_iov_length(minor_status, context_handle,
     261             :                                        conf_req_flag, qop_req, conf_state,
     262             :                                        iov, 5);
     263           0 :     if (GSS_ERROR(major_status))
     264           0 :         return major_status;
     265             : 
     266           0 :     for (i = 0, output_message_buffer->length = 0; i < 5; i++) {
     267           0 :         if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
     268           0 :             continue;
     269             : 
     270           0 :         output_message_buffer->length += iov[i].buffer.length;
     271             :     }
     272             : 
     273           0 :     output_message_buffer->value = malloc(output_message_buffer->length);
     274           0 :     if (output_message_buffer->value == NULL) {
     275           0 :         *minor_status = ENOMEM;
     276           0 :         return GSS_S_FAILURE;
     277             :     }
     278             : 
     279           0 :     for (i = 0, p = output_message_buffer->value; i < 5; i++) {
     280           0 :         if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY)
     281           0 :             continue;
     282           0 :         else if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA)
     283           0 :             memcpy(p, input_payload_buffer->value, input_payload_buffer->length);
     284             : 
     285           0 :         iov[i].buffer.value = p;
     286           0 :         p += iov[i].buffer.length;
     287             :     }
     288             : 
     289           0 :     major_status = gss_wrap_iov(minor_status, context_handle, conf_req_flag,
     290             :                                 qop_req, conf_state, iov, 5);
     291           0 :     if (GSS_ERROR(major_status))
     292           0 :         gss_release_buffer(&tmp, output_message_buffer);
     293             : 
     294           0 :     return major_status;
     295             : }
     296             : 
     297             : /*
     298             :  * AEAD unwrap for a single piece of associated data, for compatibility
     299             :  * with MIT and as specified by draft-howard-gssapi-aead-00.txt.
     300             :  *
     301             :  * @ingroup gssapi
     302             :  */
     303             : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
     304           0 : gss_unwrap_aead(OM_uint32 *minor_status,
     305             :                 gss_ctx_id_t context_handle,
     306             :                 gss_buffer_t input_message_buffer,
     307             :                 gss_buffer_t input_assoc_buffer,
     308             :                 gss_buffer_t output_payload_buffer,
     309             :                 int *conf_state,
     310             :                 gss_qop_t *qop_state)
     311             : {
     312           0 :     OM_uint32 major_status, tmp;
     313           0 :     gss_iov_buffer_desc iov[3];
     314             : 
     315           0 :     memset(iov, 0, sizeof(iov));
     316             : 
     317           0 :     iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
     318           0 :     iov[0].buffer = *input_message_buffer;
     319             : 
     320           0 :     iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
     321           0 :     if (input_assoc_buffer)
     322           0 :         iov[1].buffer = *input_assoc_buffer;
     323             : 
     324           0 :     iov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE;
     325             : 
     326           0 :     major_status = gss_unwrap_iov(minor_status, context_handle, conf_state,
     327             :                                   qop_state, iov, 3);
     328           0 :     if (GSS_ERROR(major_status))
     329           0 :         gss_release_iov_buffer(&tmp, &iov[2], 1);
     330             :     else
     331           0 :         *output_payload_buffer = iov[2].buffer;
     332             : 
     333           0 :     return major_status;
     334             : }

Generated by: LCOV version 1.14