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