Based on the 'IV_NCP=2' mechanism described in
http://permalink.gmane.org/gmane.network.openvpn.devel/9385.
This is the first patch of a set that adds support for cipher negotiation.
Follow-up patches will add ways to restrict or disable the mechanism, and
add server-side support.
v2:
* Account for crypto overhead through struct frame. This is less
transparant, but the code has been built to work this way. The
previous approach didn't work with TCP mode (or --port-share).
* Calculate the link-mtu sent in the options string based on the crypto
parameters specified in the config file (prevents link-mtu warnings in
older peers when connecting).
v3:
* Use existing max_int() function, instead of new MAX() macro.
* Fix typo in comment.
* Do not regenerate keys if the server sends a second push msg
* Only push IV_NCP if we're pull-client (and thus can do NCP)
v4:
* Fix rebase errors (OPT_P_NCP sneaked in, but is not introduced till 4/5,
and tls_peer_info_ncp_ver() is not needed until 5/5).
* Don't remove comment about key_id increment behaviour in init.c (but
still add the extra comments in the .h files).
Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1467149635-9726-1-git-send-email-steffan@karger.me>
URL: http://article.gmane.org/gmane.network.openvpn.devel/12007
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
|
36 | 36 |
#include "crypto.h" |
37 | 37 |
#include "error.h" |
38 |
+#include "integer.h" |
|
38 | 39 |
#include "misc.h" |
39 | 40 |
|
40 | 41 |
#include "memdbg.h" |
... | ... |
@@ -709,10 +710,6 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
709 | 709 |
return ret; |
710 | 710 |
} |
711 | 711 |
|
712 |
-/* |
|
713 |
- * How many bytes will we add to frame buffer for a given |
|
714 |
- * set of crypto options? |
|
715 |
- */ |
|
716 | 712 |
void |
717 | 713 |
crypto_adjust_frame_parameters(struct frame *frame, |
718 | 714 |
const struct key_type* kt, |
... | ... |
@@ -746,6 +743,14 @@ crypto_adjust_frame_parameters(struct frame *frame, |
746 | 746 |
__func__, crypto_overhead); |
747 | 747 |
} |
748 | 748 |
|
749 |
+size_t |
|
750 |
+crypto_max_overhead(void) |
|
751 |
+{ |
|
752 |
+ return packet_id_size(true) + OPENVPN_MAX_IV_LENGTH + |
|
753 |
+ OPENVPN_MAX_CIPHER_BLOCK_SIZE + |
|
754 |
+ max_int (OPENVPN_MAX_HMAC_SIZE, OPENVPN_AEAD_TAG_LENGTH); |
|
755 |
+} |
|
756 |
+ |
|
749 | 757 |
/* |
750 | 758 |
* Build a struct key_type. |
751 | 759 |
*/ |
... | ... |
@@ -774,6 +779,9 @@ init_key_type (struct key_type *kt, const char *ciphername, |
774 | 774 |
#endif |
775 | 775 |
)) |
776 | 776 |
msg (M_FATAL, "Cipher '%s' mode not supported", ciphername); |
777 |
+ |
|
778 |
+ if (OPENVPN_MAX_CIPHER_BLOCK_SIZE < cipher_kt_block_size(kt->cipher)) |
|
779 |
+ msg (M_FATAL, "Cipher '%s' not allowed: block size too big.", ciphername); |
|
777 | 780 |
} |
778 | 781 |
else |
779 | 782 |
{ |
... | ... |
@@ -785,6 +793,9 @@ init_key_type (struct key_type *kt, const char *ciphername, |
785 | 785 |
if (!aead_cipher) { /* Ignore auth for AEAD ciphers */ |
786 | 786 |
kt->digest = md_kt_get (authname); |
787 | 787 |
kt->hmac_length = md_kt_size (kt->digest); |
788 |
+ |
|
789 |
+ if (OPENVPN_MAX_HMAC_SIZE < kt->hmac_length) |
|
790 |
+ msg (M_FATAL, "HMAC '%s' not allowed: digest size too big.", authname); |
|
788 | 791 |
} |
789 | 792 |
} |
790 | 793 |
else if (!aead_cipher) |
... | ... |
@@ -226,6 +226,7 @@ struct key_ctx_bi |
226 | 226 |
* direction. */ |
227 | 227 |
struct key_ctx decrypt; /**< cipher and/or HMAC contexts for |
228 | 228 |
* receiving direction. */ |
229 |
+ bool initialized; |
|
229 | 230 |
}; |
230 | 231 |
|
231 | 232 |
/** |
... | ... |
@@ -385,6 +386,7 @@ bool openvpn_decrypt (struct buffer *buf, struct buffer work, |
385 | 385 |
|
386 | 386 |
/** @} name Functions for performing security operations on data channel packets */ |
387 | 387 |
|
388 |
+/** Calculate crypto overhead and adjust frame to account for that */ |
|
388 | 389 |
void crypto_adjust_frame_parameters(struct frame *frame, |
389 | 390 |
const struct key_type* kt, |
390 | 391 |
bool cipher_defined, |
... | ... |
@@ -392,6 +394,8 @@ void crypto_adjust_frame_parameters(struct frame *frame, |
392 | 392 |
bool packet_id, |
393 | 393 |
bool packet_id_long_form); |
394 | 394 |
|
395 |
+/** Return the worst-case OpenVPN crypto overhead (in bytes) */ |
|
396 |
+size_t crypto_max_overhead(void); |
|
395 | 397 |
|
396 | 398 |
/* Minimum length of the nonce used by the PRNG */ |
397 | 399 |
#define NONCE_SECRET_LEN_MIN 16 |
... | ... |
@@ -41,6 +41,12 @@ |
41 | 41 |
/* TLS uses a tag of 128 bytes, let's do the same for OpenVPN */ |
42 | 42 |
#define OPENVPN_AEAD_TAG_LENGTH 16 |
43 | 43 |
|
44 |
+/* Maximum cipher block size (bytes) */ |
|
45 |
+#define OPENVPN_MAX_CIPHER_BLOCK_SIZE 32 |
|
46 |
+ |
|
47 |
+/* Maximum HMAC digest size (bytes) */ |
|
48 |
+#define OPENVPN_MAX_HMAC_SIZE 64 |
|
49 |
+ |
|
44 | 50 |
/** Struct used in cipher name translation table */ |
45 | 51 |
typedef struct { |
46 | 52 |
const char *openvpn_name; /**< Cipher name used by OpenVPN */ |
... | ... |
@@ -1825,6 +1825,7 @@ pull_permission_mask (const struct context *c) |
1825 | 1825 |
| OPT_P_SHAPER |
1826 | 1826 |
| OPT_P_TIMER |
1827 | 1827 |
| OPT_P_COMP |
1828 |
+ | OPT_P_CRYPTO |
|
1828 | 1829 |
| OPT_P_PERSIST |
1829 | 1830 |
| OPT_P_MESSAGES |
1830 | 1831 |
| OPT_P_EXPLICIT_NOTIFY |
... | ... |
@@ -1928,6 +1929,19 @@ do_deferred_options (struct context *c, const unsigned int found) |
1928 | 1928 |
" MTU problems", TUN_MTU_SIZE(&c->c2.frame) ); |
1929 | 1929 |
} |
1930 | 1930 |
} |
1931 |
+ |
|
1932 |
+ /* process (potentially pushed) crypto options */ |
|
1933 |
+ if (c->options.pull) |
|
1934 |
+ { |
|
1935 |
+ struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE]; |
|
1936 |
+ if (found & OPT_P_CRYPTO) |
|
1937 |
+ msg (D_PUSH, "OPTIONS IMPORT: data channel crypto options modified"); |
|
1938 |
+ /* Do not regenerate keys if server sends an extra push request */ |
|
1939 |
+ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized) |
|
1940 |
+ { |
|
1941 |
+ tls_session_update_crypto_params(session, &c->options, &c->c2.frame); |
|
1942 |
+ } |
|
1943 |
+ } |
|
1931 | 1944 |
#endif |
1932 | 1945 |
} |
1933 | 1946 |
|
... | ... |
@@ -2043,6 +2057,7 @@ frame_finalize_options (struct context *c, const struct options *o) |
2043 | 2043 |
|FRAME_HEADROOM_MARKER_READ_STREAM); |
2044 | 2044 |
} |
2045 | 2045 |
|
2046 |
+ frame_add_to_extra_buffer (&c->c2.frame, PAYLOAD_ALIGN); |
|
2046 | 2047 |
frame_finalize (&c->c2.frame, |
2047 | 2048 |
o->ce.link_mtu_defined, |
2048 | 2049 |
o->ce.link_mtu, |
... | ... |
@@ -2298,12 +2313,18 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
2298 | 2298 |
/* In short form, unique datagram identifier is 32 bits, in long form 64 bits */ |
2299 | 2299 |
packet_id_long_form = cipher_kt_mode_ofb_cfb (c->c1.ks.key_type.cipher); |
2300 | 2300 |
|
2301 |
- /* Compute MTU parameters */ |
|
2302 |
- crypto_adjust_frame_parameters (&c->c2.frame, |
|
2303 |
- &c->c1.ks.key_type, |
|
2304 |
- options->ciphername_defined, |
|
2305 |
- options->use_iv, |
|
2306 |
- options->replay, packet_id_long_form); |
|
2301 |
+ /* Compute MTU parameters (postpone if we pull options) */ |
|
2302 |
+ if (c->options.pull) |
|
2303 |
+ { |
|
2304 |
+ /* Account for worst-case crypto overhead before allocating buffers */ |
|
2305 |
+ frame_add_to_extra_frame (&c->c2.frame, crypto_max_overhead()); |
|
2306 |
+ } |
|
2307 |
+ else |
|
2308 |
+ { |
|
2309 |
+ crypto_adjust_frame_parameters(&c->c2.frame, &c->c1.ks.key_type, |
|
2310 |
+ options->ciphername_defined, options->use_iv, options->replay, |
|
2311 |
+ packet_id_long_form); |
|
2312 |
+ } |
|
2307 | 2313 |
tls_adjust_frame_parameters (&c->c2.frame); |
2308 | 2314 |
|
2309 | 2315 |
/* Set all command-line TLS-related options */ |
... | ... |
@@ -2334,6 +2355,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
2334 | 2334 |
to.renegotiate_packets = options->renegotiate_packets; |
2335 | 2335 |
to.renegotiate_seconds = options->renegotiate_seconds; |
2336 | 2336 |
to.single_session = options->single_session; |
2337 |
+ to.pull = options->pull; |
|
2337 | 2338 |
#ifdef ENABLE_PUSH_PEER_INFO |
2338 | 2339 |
if (options->push_peer_info) /* all there is */ |
2339 | 2340 |
to.push_peer_info_detail = 2; |
... | ... |
@@ -2965,6 +2965,38 @@ pre_pull_restore (struct options *o, struct gc_arena *gc) |
2965 | 2965 |
|
2966 | 2966 |
#ifdef ENABLE_OCC |
2967 | 2967 |
|
2968 |
+/** |
|
2969 |
+ * Calculate the link-mtu to advertise to our peer. The actual value is not |
|
2970 |
+ * relevant, because we will possibly perform data channel cipher negotiation |
|
2971 |
+ * after this, but older clients will log warnings if we do not supply them the |
|
2972 |
+ * value they expect. This assumes that the traditional cipher/auth directives |
|
2973 |
+ * in the config match the config of the peer. |
|
2974 |
+ */ |
|
2975 |
+static size_t |
|
2976 |
+calc_options_string_link_mtu(const struct options *o, const struct frame *frame) |
|
2977 |
+{ |
|
2978 |
+ size_t link_mtu = EXPANDED_SIZE (frame); |
|
2979 |
+#ifdef ENABLE_CRYPTO |
|
2980 |
+ if (o->pull || o->mode == MODE_SERVER) |
|
2981 |
+ { |
|
2982 |
+ struct frame fake_frame = *frame; |
|
2983 |
+ struct key_type fake_kt; |
|
2984 |
+ init_key_type (&fake_kt, o->ciphername, o->ciphername_defined, |
|
2985 |
+ o->authname, o->authname_defined, o->keysize, true, false); |
|
2986 |
+ frame_add_to_extra_frame (&fake_frame, -(crypto_max_overhead())); |
|
2987 |
+ crypto_adjust_frame_parameters (&fake_frame, &fake_kt, |
|
2988 |
+ o->ciphername_defined, o->use_iv, o->replay, |
|
2989 |
+ cipher_kt_mode_ofb_cfb (fake_kt.cipher)); |
|
2990 |
+ frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu, |
|
2991 |
+ o->ce.tun_mtu_defined, o->ce.tun_mtu); |
|
2992 |
+ msg (D_MTU_DEBUG, "%s: link-mtu %zu -> %d", __func__, link_mtu, |
|
2993 |
+ EXPANDED_SIZE (&fake_frame)); |
|
2994 |
+ link_mtu = EXPANDED_SIZE (&fake_frame); |
|
2995 |
+ } |
|
2996 |
+#endif |
|
2997 |
+ return link_mtu; |
|
2998 |
+} |
|
2999 |
+ |
|
2968 | 3000 |
/* |
2969 | 3001 |
* Build an options string to represent data channel encryption options. |
2970 | 3002 |
* This string must match exactly between peers. The keysize is checked |
... | ... |
@@ -3009,7 +3041,6 @@ pre_pull_restore (struct options *o, struct gc_arena *gc) |
3009 | 3009 |
* --tls-server [matched with --tls-client on |
3010 | 3010 |
* the other end of the connection] |
3011 | 3011 |
*/ |
3012 |
- |
|
3013 | 3012 |
char * |
3014 | 3013 |
options_string (const struct options *o, |
3015 | 3014 |
const struct frame *frame, |
... | ... |
@@ -3027,7 +3058,7 @@ options_string (const struct options *o, |
3027 | 3027 |
*/ |
3028 | 3028 |
|
3029 | 3029 |
buf_printf (&out, ",dev-type %s", dev_type_string (o->dev, o->dev_type)); |
3030 |
- buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame)); |
|
3030 |
+ buf_printf (&out, ",link-mtu %zu", calc_options_string_link_mtu(o, frame)); |
|
3031 | 3031 |
buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame)); |
3032 | 3032 |
buf_printf (&out, ",proto %s", proto_remote (o->ce.proto, remote)); |
3033 | 3033 |
|
... | ... |
@@ -1613,6 +1613,7 @@ generate_key_expansion (struct key_ctx_bi *key, |
1613 | 1613 |
key_ctx_update_implicit_iv (&key->decrypt, key2.keys[1-(int)server].hmac, |
1614 | 1614 |
MAX_HMAC_KEY_LENGTH); |
1615 | 1615 |
|
1616 |
+ key->initialized = true; |
|
1616 | 1617 |
ret = true; |
1617 | 1618 |
|
1618 | 1619 |
exit: |
... | ... |
@@ -1639,6 +1640,50 @@ key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len) { |
1639 | 1639 |
} |
1640 | 1640 |
} |
1641 | 1641 |
|
1642 |
+bool |
|
1643 |
+tls_session_update_crypto_params(struct tls_session *session, |
|
1644 |
+ const struct options *options, struct frame *frame) |
|
1645 |
+{ |
|
1646 |
+ bool ret = false; |
|
1647 |
+ struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ |
|
1648 |
+ |
|
1649 |
+ ASSERT (!session->opt->server); |
|
1650 |
+ ASSERT (ks->authenticated); |
|
1651 |
+ |
|
1652 |
+ init_key_type (&session->opt->key_type, options->ciphername, |
|
1653 |
+ options->ciphername_defined, options->authname, options->authname_defined, |
|
1654 |
+ options->keysize, true, true); |
|
1655 |
+ |
|
1656 |
+ bool packet_id_long_form = cipher_kt_mode_ofb_cfb (session->opt->key_type.cipher); |
|
1657 |
+ session->opt->crypto_flags_and &= ~(CO_PACKET_ID_LONG_FORM); |
|
1658 |
+ if (packet_id_long_form) |
|
1659 |
+ session->opt->crypto_flags_and = CO_PACKET_ID_LONG_FORM; |
|
1660 |
+ |
|
1661 |
+ /* Update frame parameters: undo worst-case overhead, add actual overhead */ |
|
1662 |
+ frame_add_to_extra_frame (frame, -(crypto_max_overhead())); |
|
1663 |
+ crypto_adjust_frame_parameters (frame, &session->opt->key_type, |
|
1664 |
+ options->ciphername_defined, options->use_iv, options->replay, |
|
1665 |
+ packet_id_long_form); |
|
1666 |
+ frame_finalize(frame, options->ce.link_mtu_defined, options->ce.link_mtu, |
|
1667 |
+ options->ce.tun_mtu_defined, options->ce.tun_mtu); |
|
1668 |
+ frame_print (frame, D_MTU_INFO, "Data Channel MTU parms"); |
|
1669 |
+ |
|
1670 |
+ if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi, |
|
1671 |
+ &session->opt->key_type, |
|
1672 |
+ ks->key_src, |
|
1673 |
+ &session->session_id, |
|
1674 |
+ &ks->session_id_remote, |
|
1675 |
+ false)) |
|
1676 |
+ { |
|
1677 |
+ msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed"); |
|
1678 |
+ goto cleanup; |
|
1679 |
+ } |
|
1680 |
+ ret = true; |
|
1681 |
+cleanup: |
|
1682 |
+ CLEAR (*ks->key_src); |
|
1683 |
+ return ret; |
|
1684 |
+} |
|
1685 |
+ |
|
1642 | 1686 |
static bool |
1643 | 1687 |
random_bytes_to_buf (struct buffer *buf, |
1644 | 1688 |
uint8_t *out, |
... | ... |
@@ -1885,6 +1930,10 @@ push_peer_info(struct buffer *buf, struct tls_session *session) |
1885 | 1885 |
/* support for P_DATA_V2 */ |
1886 | 1886 |
buf_printf(&out, "IV_PROTO=2\n"); |
1887 | 1887 |
|
1888 |
+ /* support for Negotiable Crypto Paramters */ |
|
1889 |
+ if (session->opt->pull) |
|
1890 |
+ buf_printf(&out, "IV_NCP=2\n"); |
|
1891 |
+ |
|
1888 | 1892 |
/* push compression status */ |
1889 | 1893 |
#ifdef USE_COMP |
1890 | 1894 |
comp_generate_peer_info_string(&session->opt->comp_options, &out); |
... | ... |
@@ -2211,9 +2260,11 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
2211 | 2211 |
} |
2212 | 2212 |
|
2213 | 2213 |
/* |
2214 |
- * Generate tunnel keys if client |
|
2214 |
+ * Generate tunnel keys if we're a client. |
|
2215 |
+ * If --pull is enabled, the first key generation is postponed until after the |
|
2216 |
+ * pull/push, so we can process pushed cipher directives. |
|
2215 | 2217 |
*/ |
2216 |
- if (!session->opt->server) |
|
2218 |
+ if (!session->opt->server && (!session->opt->pull || ks->key_id > 0)) |
|
2217 | 2219 |
{ |
2218 | 2220 |
if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi, |
2219 | 2221 |
&session->opt->key_type, |
... | ... |
@@ -2225,7 +2276,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
2225 | 2225 |
msg (D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed"); |
2226 | 2226 |
goto error; |
2227 | 2227 |
} |
2228 |
- |
|
2228 |
+ |
|
2229 | 2229 |
CLEAR (*ks->key_src); |
2230 | 2230 |
} |
2231 | 2231 |
|
... | ... |
@@ -2891,6 +2942,14 @@ tls_pre_decrypt (struct tls_multi *multi, |
2891 | 2891 |
#endif |
2892 | 2892 |
&& (floated || link_socket_actual_match (from, &ks->remote_addr))) |
2893 | 2893 |
{ |
2894 |
+ if (!ks->crypto_options.key_ctx_bi.initialized) |
|
2895 |
+ { |
|
2896 |
+ msg (D_TLS_DEBUG_LOW, |
|
2897 |
+ "Key %s [%d] not initialized (yet), dropping packet.", |
|
2898 |
+ print_link_socket_actual (from, &gc), key_id); |
|
2899 |
+ goto error_lite; |
|
2900 |
+ } |
|
2901 |
+ |
|
2894 | 2902 |
/* return appropriate data channel decrypt key in opt */ |
2895 | 2903 |
*opt = &ks->crypto_options; |
2896 | 2904 |
if (op == P_DATA_V2) |
... | ... |
@@ -3428,6 +3487,7 @@ tls_pre_encrypt (struct tls_multi *multi, |
3428 | 3428 |
struct key_state *ks = multi->key_scan[i]; |
3429 | 3429 |
if (ks->state >= S_ACTIVE |
3430 | 3430 |
&& ks->authenticated |
3431 |
+ && ks->crypto_options.key_ctx_bi.initialized |
|
3431 | 3432 |
#ifdef ENABLE_DEF_AUTH |
3432 | 3433 |
&& !ks->auth_deferred |
3433 | 3434 |
#endif |
... | ... |
@@ -475,6 +475,20 @@ bool tls_rec_payload (struct tls_multi *multi, |
475 | 475 |
void tls_update_remote_addr (struct tls_multi *multi, |
476 | 476 |
const struct link_socket_actual *addr); |
477 | 477 |
|
478 |
+/** |
|
479 |
+ * Update TLS session crypto parameters (cipher and auth) and derive data |
|
480 |
+ * channel keys based on the supplied options. |
|
481 |
+ * |
|
482 |
+ * @param session The TLS session to update. |
|
483 |
+ * @param options The options to use when updating session. |
|
484 |
+ * @param frame The frame options for this session (frame overhead is |
|
485 |
+ * adjusted based on the selected cipher/auth). |
|
486 |
+ * |
|
487 |
+ * @return true if updating succeeded, false otherwise. |
|
488 |
+ */ |
|
489 |
+bool tls_session_update_crypto_params(struct tls_session *session, |
|
490 |
+ const struct options *options, struct frame *frame); |
|
491 |
+ |
|
478 | 492 |
#ifdef MANAGEMENT_DEF_AUTH |
479 | 493 |
static inline char * |
480 | 494 |
tls_get_peer_info(const struct tls_multi *multi) |
... | ... |
@@ -149,7 +149,12 @@ struct key_source2 { |
149 | 149 |
struct key_state |
150 | 150 |
{ |
151 | 151 |
int state; |
152 |
- int key_id; /* inherited from struct tls_session below */ |
|
152 |
+ |
|
153 |
+ /** |
|
154 |
+ * Key id for this key_state, inherited from struct tls_session. |
|
155 |
+ * @see tls_session::key_id. |
|
156 |
+ */ |
|
157 |
+ int key_id; |
|
153 | 158 |
|
154 | 159 |
struct key_state_ssl ks_ssl; /* contains SSL object and BIOs for the control channel */ |
155 | 160 |
|
... | ... |
@@ -231,6 +236,7 @@ struct tls_options |
231 | 231 |
#ifdef ENABLE_OCC |
232 | 232 |
bool disable_occ; |
233 | 233 |
#endif |
234 |
+ bool pull; |
|
234 | 235 |
#ifdef ENABLE_PUSH_PEER_INFO |
235 | 236 |
int push_peer_info_detail; |
236 | 237 |
#endif |
... | ... |
@@ -367,7 +373,13 @@ struct tls_session |
367 | 367 |
|
368 | 368 |
int initial_opcode; /* our initial P_ opcode */ |
369 | 369 |
struct session_id session_id; /* our random session ID */ |
370 |
- int key_id; /* increments with each soft reset (for key renegotiation) */ |
|
370 |
+ |
|
371 |
+ /** |
|
372 |
+ * The current active key id, used to keep track of renegotiations. |
|
373 |
+ * key_id increments with each soft reset to KEY_ID_MASK then recycles back |
|
374 |
+ * to 1. This way you know that if key_id is 0, it is the first key. |
|
375 |
+ */ |
|
376 |
+ int key_id; |
|
371 | 377 |
|
372 | 378 |
int limit_next; /* used for traffic shaping on the control channel */ |
373 | 379 |
|