krb5 commit: Replace i_vector with cstate in auth context

Greg Hudson ghudson at MIT.EDU
Thu Feb 7 13:09:52 EST 2013


https://github.com/krb5/krb5/commit/6d78c1e7b1588500050a044c2c831994c9becaaa
commit 6d78c1e7b1588500050a044c2c831994c9becaaa
Author: Greg Hudson <ghudson at mit.edu>
Date:   Sun Feb 3 14:44:22 2013 -0500

    Replace i_vector with cstate in auth context
    
    Use a proper cipher state in the auth context structure, and free it
    when the auth context is freed.  Simplify mk_priv/rd_priv accordingly.

 src/lib/krb5/krb/auth_con.c |   38 +++++++++++++++----------
 src/lib/krb5/krb/auth_con.h |    2 +-
 src/lib/krb5/krb/mk_priv.c  |   18 ++---------
 src/lib/krb5/krb/rd_priv.c  |   11 ++-----
 src/lib/krb5/krb/ser_actx.c |   65 ++++++++++++------------------------------
 src/lib/krb5/krb/t_ser.c    |   11 -------
 6 files changed, 50 insertions(+), 95 deletions(-)

diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
index 986d439..c86a4af 100644
--- a/src/lib/krb5/krb/auth_con.c
+++ b/src/lib/krb5/krb/auth_con.c
@@ -70,6 +70,7 @@ krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
         krb5_k_free_key(context, auth_context->send_subkey);
     if (auth_context->recv_subkey)
         krb5_k_free_key(context, auth_context->recv_subkey);
+    zapfree(auth_context->cstate.data, auth_context->cstate.length);
     if (auth_context->rcache)
         krb5_rc_close(context, auth_context->rcache);
     if (auth_context->permitted_etypes)
@@ -315,20 +316,27 @@ krb5_error_code KRB5_CALLCONV
 krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context)
 {
     krb5_error_code ret;
-    krb5_data cstate;
-
-    if (auth_context->key) {
-        ret = krb5_c_init_state(context, &auth_context->key->keyblock, 0,
-                                &cstate);
-        if (ret)
-            return ret;
-        auth_context->i_vector = (krb5_pointer)calloc(1,cstate.length);
-        krb5_c_free_state(context, &auth_context->key->keyblock, &cstate);
-        if (auth_context->i_vector == NULL)
-            return ENOMEM;
-        return 0;
-    }
-    return EINVAL; /* XXX need an error for no keyblock */
+    krb5_enctype enctype;
+
+    if (auth_context->key == NULL)
+        return EINVAL;
+    ret = krb5_c_init_state(context, &auth_context->key->keyblock,
+                            KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
+                            &auth_context->cstate);
+    if (ret)
+        return ret;
+
+    /*
+     * Historically we used a zero-filled buffer of the enctype block size.
+     * This matches every existing enctype except RC4 (which has a block size
+     * of 1) and des-cbc-crc (which uses the key instead of a zero-filled
+     * buffer).  Special-case des-cbc-crc to remain interoperable.
+     */
+    enctype = krb5_k_key_enctype(context, auth_context->key);
+    if (enctype == ENCTYPE_DES_CBC_CRC)
+        zap(auth_context->cstate.data, auth_context->cstate.length);
+
+    return 0;
 }
 
 krb5_error_code
@@ -345,7 +353,7 @@ krb5_auth_con_setivector(krb5_context context, krb5_auth_context auth_context, k
 krb5_error_code
 krb5_auth_con_getivector(krb5_context context, krb5_auth_context auth_context, krb5_pointer *ivector)
 {
-    *ivector = auth_context->i_vector;
+    *ivector = auth_context->cstate.data;
     return 0;
 }
 
diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h
index 94d2c51..821b41e 100644
--- a/src/lib/krb5/krb/auth_con.h
+++ b/src/lib/krb5/krb/auth_con.h
@@ -19,7 +19,7 @@ struct _krb5_auth_context {
     krb5_authenticator *authentp;               /* mk_req, rd_req, mk_rep, ...*/
     krb5_cksumtype      req_cksumtype;          /* mk_safe, ... */
     krb5_cksumtype      safe_cksumtype;         /* mk_safe, ... */
-    krb5_pointer        i_vector;               /* mk_priv, rd_priv only */
+    krb5_data           cstate;                 /* mk_priv, rd_priv only */
     krb5_rcache         rcache;
     krb5_enctype      * permitted_etypes;       /* rd_req */
     krb5_mk_req_checksum_func checksum_func;
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 4b63f25..b3d9e68 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -32,13 +32,13 @@ static krb5_error_code
 mk_priv_basic(krb5_context context, const krb5_data *userdata,
               krb5_key key, krb5_replay_data *replaydata,
               krb5_address *local_addr, krb5_address *remote_addr,
-              krb5_pointer i_vector, krb5_data *outbuf)
+              krb5_data *cstate, krb5_data *outbuf)
 {
     krb5_enctype        enctype = krb5_k_key_enctype(context, key);
     krb5_error_code     retval;
     krb5_priv           privmsg;
     krb5_priv_enc_part  privmsg_enc_part;
-    krb5_data           *scratch1, *scratch2, cstate, ivdata;
+    krb5_data           *scratch1, *scratch2;
     size_t              enclen;
 
     privmsg.enc_part.kvno = 0;  /* XXX allow user-set? */
@@ -69,19 +69,9 @@ mk_priv_basic(krb5_context context, const krb5_data *userdata,
         goto clean_scratch;
     }
 
-    /* call the encryption routine */
-    if (i_vector) {
-        if ((retval = krb5_c_init_state(context, &key->keyblock, 0, &cstate)))
-            goto clean_encpart;
-
-        ivdata.length = cstate.length;
-        ivdata.data = i_vector;
-        krb5_c_free_state(context, &key->keyblock, &cstate);
-    }
-
     if ((retval = krb5_k_encrypt(context, key,
                                  KRB5_KEYUSAGE_KRB_PRIV_ENCPART,
-                                 i_vector?&ivdata:0,
+                                 (cstate->length > 0) ? cstate : NULL,
                                  scratch1, &privmsg.enc_part)))
         goto clean_encpart;
 
@@ -195,7 +185,7 @@ krb5_mk_priv(krb5_context context, krb5_auth_context auth_context,
 
         if ((retval = mk_priv_basic(context, userdata, key, &replaydata,
                                     plocal_fulladdr, premote_fulladdr,
-                                    auth_context->i_vector, &buf))) {
+                                    &auth_context->cstate, &buf))) {
             CLEANUP_DONE();
             goto error;
         }
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index 94f6a66..2912ab1b 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -51,7 +51,7 @@ rd_priv_basic(krb5_context context, krb5_auth_context ac,
     krb5_priv           * privmsg;
     krb5_data             scratch;
     krb5_priv_enc_part  * privmsg_enc_part;
-    krb5_data             cstate, ivdata, *iv = NULL;
+    krb5_data             *iv = NULL;
 
     if (!krb5_is_krb_priv(inbuf))
         return KRB5KRB_AP_ERR_MSG_TYPE;
@@ -60,13 +60,8 @@ rd_priv_basic(krb5_context context, krb5_auth_context ac,
     if ((retval = decode_krb5_priv(inbuf, &privmsg)))
         return retval;
 
-    if (ac->i_vector != NULL) {
-        if ((retval = krb5_c_init_state(context, &key->keyblock, 0, &cstate)))
-            goto cleanup_privmsg;
-        ivdata = make_data(ac->i_vector, cstate.length);
-        iv = &ivdata;
-        krb5_c_free_state(context, &key->keyblock, &cstate);
-    }
+    if (ac->cstate.length > 0)
+        iv = &ac->cstate;
 
     scratch.length = privmsg->enc_part.ciphertext.length;
     if (!(scratch.data = malloc(scratch.length))) {
diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c
index b366ff3..d866fe3 100644
--- a/src/lib/krb5/krb/ser_actx.c
+++ b/src/lib/krb5/krb/ser_actx.c
@@ -71,7 +71,6 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
     krb5_error_code     kret;
     krb5_auth_context   auth_context;
     size_t              required;
-    krb5_enctype        enctype;
 
     /*
      * krb5_auth_context requires at minimum:
@@ -88,14 +87,7 @@ krb5_auth_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
     if ((auth_context = (krb5_auth_context) arg)) {
         kret = 0;
 
-        /* Calculate size required by i_vector - ptooey */
-        if (auth_context->i_vector && auth_context->key) {
-            enctype = krb5_k_key_enctype(kcontext, auth_context->key);
-            kret = krb5_c_block_size(kcontext, enctype, &required);
-        } else {
-            required = 0;
-        }
-
+        required = auth_context->cstate.length;
         required += sizeof(krb5_int32)*8;
 
         /* Calculate size required by remote_addr, if appropriate */
@@ -192,9 +184,6 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
     size_t              required;
     krb5_octet          *bp;
     size_t              remain;
-    size_t              obuf;
-    krb5_int32          obuf32;
-    krb5_enctype        enctype;
 
     required = 0;
     bp = *buffer;
@@ -218,28 +207,14 @@ krb5_auth_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octe
             (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype,
                                        &bp, &remain);
 
-            kret = 0;
-
-            /* Now figure out the number of bytes for i_vector and write it */
-            if (auth_context->i_vector) {
-                enctype = krb5_k_key_enctype(kcontext, auth_context->key);
-                kret = krb5_c_block_size(kcontext, enctype, &obuf);
-            } else {
-                obuf = 0;
-            }
-
-            /* Convert to signed 32 bit integer */
-            obuf32 = obuf;
-            if (kret == 0 && obuf > KRB5_INT32_MAX)
-                kret = EINVAL;
-            if (!kret)
-                (void) krb5_ser_pack_int32(obuf32, &bp, &remain);
+            /* Write the cipher state */
+            (void) krb5_ser_pack_int32(auth_context->cstate.length, &bp,
+                                       &remain);
+            (void) krb5_ser_pack_bytes((krb5_octet *)auth_context->cstate.data,
+                                       auth_context->cstate.length,
+                                       &bp, &remain);
 
-            /* Now copy i_vector */
-            if (!kret && auth_context->i_vector)
-                (void) krb5_ser_pack_bytes(auth_context->i_vector,
-                                           obuf,
-                                           &bp, &remain);
+            kret = 0;
 
             /* Now handle remote_addr, if appropriate */
             if (!kret && auth_context->remote_addr) {
@@ -369,7 +344,7 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc
     krb5_int32          ibuf;
     krb5_octet          *bp;
     size_t              remain;
-    krb5_int32          ivlen;
+    krb5_int32          cstate_len;
     krb5_int32          tag;
 
     bp = *buffer;
@@ -406,18 +381,16 @@ krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_oc
             (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
             auth_context->safe_cksumtype = (krb5_cksumtype) ibuf;
 
-            /* Get length of i_vector */
-            (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain);
-
-            if (ivlen) {
-                if ((auth_context->i_vector =
-                     (krb5_pointer) malloc((size_t)ivlen)))
-                    kret = krb5_ser_unpack_bytes(auth_context->i_vector,
-                                                 (size_t) ivlen,
-                                                 &bp,
-                                                 &remain);
-                else
-                    kret = ENOMEM;
+            /* Get length of cstate */
+            (void) krb5_ser_unpack_int32(&cstate_len, &bp, &remain);
+
+            if (cstate_len) {
+                kret = alloc_data(&auth_context->cstate, cstate_len);
+                if (!kret) {
+                    kret = krb5_ser_unpack_bytes((krb5_octet *)
+                                                 auth_context->cstate.data,
+                                                 cstate_len, &bp, &remain);
+                }
             }
             else
                 kret = 0;
diff --git a/src/lib/krb5/krb/t_ser.c b/src/lib/krb5/krb/t_ser.c
index b16c2dc..692d89d 100644
--- a/src/lib/krb5/krb/t_ser.c
+++ b/src/lib/krb5/krb/t_ser.c
@@ -135,13 +135,6 @@ ser_data(int verbose, char *msg, krb5_pointer ctx, krb5_magic dtype)
                 krb5_free_context((krb5_context) nctx);
                 break;
             case KV5M_AUTH_CONTEXT:
-                if (nctx) {
-                    krb5_auth_context   actx;
-
-                    actx = (krb5_auth_context) nctx;
-                    if (actx->i_vector)
-                        free(actx->i_vector);
-                }
                 krb5_auth_con_free(ser_ctx, (krb5_auth_context) nctx);
                 break;
             case KV5M_CCACHE:
@@ -303,10 +296,6 @@ ser_acontext_test(krb5_context kcontext, int verbose)
                 !(kret = ser_data(verbose, "> Auth context with new vector",
                                   (krb5_pointer) actx,
                                   KV5M_AUTH_CONTEXT)) &&
-                (free(actx->i_vector), actx->i_vector) &&
-                !(kret = krb5_auth_con_setivector(kcontext, actx,
-                                                  (krb5_pointer) print_erep)
-                ) &&
                 !(kret = ser_data(verbose, "> Auth context with set vector",
                                   (krb5_pointer) actx,
                                   KV5M_AUTH_CONTEXT))) {


More information about the cvs-krb5 mailing list