+ char *p, *end;
+ uint32_t v2_flags = 0;
+ uint32_t enctype;
+ uint32_t keysize;
+
+ if (!(buf->value = calloc(1, MAX_CTX_LEN)))
+ goto out_err;
+ p = buf->value;
+ end = buf->value + MAX_CTX_LEN;
+
+ /* Version 2 */
+ if (lctx->initiate)
+ v2_flags |= KRB5_CTX_FLAG_INITIATOR;
+ if (lctx->protocol != 0)
+ v2_flags |= KRB5_CTX_FLAG_CFX;
+ if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
+ v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
+
+ if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
+ if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
+ if (endtime)
+ *endtime = lctx->endtime;
+ if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
+
+ /* Protocol 0 here implies DES3 or RC4 */
+ printerr(2, "%s: protocol %d\n", __FUNCTION__, lctx->protocol);
+ if (lctx->protocol == 0) {
+ enctype = lctx->rfc1964_kd.ctx_key.type;
+ keysize = lctx->rfc1964_kd.ctx_key.length;
+ } else {
+ if (lctx->cfx_kd.have_acceptor_subkey) {
+ enctype = lctx->cfx_kd.acceptor_subkey.type;
+ keysize = lctx->cfx_kd.acceptor_subkey.length;
+ } else {
+ enctype = lctx->cfx_kd.ctx_key.type;
+ keysize = lctx->cfx_kd.ctx_key.length;
+ }
+ }
+ printerr(2, "%s: serializing key with enctype %d and size %d\n",
+ __FUNCTION__, enctype, keysize);
+
+ if (WRITE_BYTES(&p, end, enctype)) goto out_err;
+
+ if (lctx->protocol == 0) {
+ if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
+ lctx->rfc1964_kd.ctx_key.length))
+ goto out_err;
+ } else {
+ if (lctx->cfx_kd.have_acceptor_subkey) {
+ if (write_bytes(&p, end,
+ lctx->cfx_kd.acceptor_subkey.data,
+ lctx->cfx_kd.acceptor_subkey.length))
+ goto out_err;
+ } else {
+ if (write_bytes(&p, end, lctx->cfx_kd.ctx_key.data,
+ lctx->cfx_kd.ctx_key.length))
+ goto out_err;
+ }
+ }
+
+ buf->length = p - (char *)buf->value;
+ return 0;
+
+out_err:
+ printerr(0, "ERROR: %s: failed serializing krb5 context for kernel\n",
+ __FUNCTION__);
+ if (buf->value) {
+ free(buf->value);
+ buf->value = NULL;
+ }
+ buf->length = 0;