+void
+set_newkeys(int mode)
+{
+ Enc *enc;
+ Mac *mac;
+ Comp *comp;
+ CipherContext *cc;
+
+ debug("newkeys: mode %d", mode);
+
+ cc = (mode == MODE_OUT) ? &send_context : &receive_context;
+ if (newkeys[mode] != NULL) {
+ debug("newkeys: rekeying");
+ /* todo: free old keys, reset compression/cipher-ctxt; */
+ memset(cc, 0, sizeof(*cc));
+ enc = &newkeys[mode]->enc;
+ mac = &newkeys[mode]->mac;
+ comp = &newkeys[mode]->comp;
+ memset(mac->key, 0, mac->key_len);
+ xfree(enc->name);
+ xfree(enc->iv);
+ xfree(enc->key);
+ xfree(mac->name);
+ xfree(mac->key);
+ xfree(comp->name);
+ xfree(newkeys[mode]);
+ }
+ newkeys[mode] = kex_get_newkeys(mode);
+ if (newkeys[mode] == NULL)
+ fatal("newkeys: no keys for mode %d", mode);
+ enc = &newkeys[mode]->enc;
+ mac = &newkeys[mode]->mac;
+ comp = &newkeys[mode]->comp;
+ if (mac->md != NULL)
+ mac->enabled = 1;
+ DBG(debug("cipher_init_context: %d", mode));
+ cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len,
+ enc->iv, enc->cipher->block_size);
+ memset(enc->iv, 0, enc->cipher->block_size);
+ memset(enc->key, 0, enc->cipher->key_len);
+ if (comp->type != 0 && comp->enabled == 0) {
+ packet_init_compression();
+ if (mode == MODE_OUT)
+ buffer_compress_init_send(6);
+ else
+ buffer_compress_init_recv();
+ comp->enabled = 1;
+ }
+}
+