OpenVPN 3 Core Library
Loading...
Searching...
No Matches
datalimit.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11//
12
13#ifndef OPENVPN_SSL_DATALIMIT_H
14#define OPENVPN_SSL_DATALIMIT_H
15
17
18namespace openvpn {
19// Helper for handling keys which can have an upper limit
20// on maximum amount of data encrypted/decrypted, such
21// as Blowfish.
23{
24 public:
25 typedef unsigned int size_type;
26
27 enum Mode
28 {
31 };
32
33 enum State
34 {
35 None = 0,
36 Green = 1,
37 Red = 2,
38 };
39
45
47 : encrypt(p.encrypt_red_limit),
48 decrypt(p.decrypt_red_limit)
49 {
50 }
51
52 State update_state(const Mode mode, const State newstate)
53 {
54 return elgible(mode, component(mode).update_state(newstate));
55 }
56
57 State add(const Mode mode, const size_type n)
58 {
59 return elgible(mode, component(mode).add(n));
60 }
61
63 {
64 return decrypt.get_state() >= Green;
65 }
66
67 static const char *mode_str(const Mode m)
68 {
69 switch (m)
70 {
71 case Encrypt:
72 return "Encrypt";
73 case Decrypt:
74 return "Decrypt";
75 default:
76 return "Mode_???";
77 }
78 }
79
80 static const char *state_str(const State s)
81 {
82 switch (s)
83 {
84 case None:
85 return "None";
86 case Green:
87 return "Green";
88 case Red:
89 return "Red";
90 default:
91 return "State_???";
92 }
93 }
94
95 private:
96 // Don't return Encrypt-Red until Decrypt-Green
97 // has been received. This confirms that the peer
98 // is now transmitting on the key ID, making it
99 // eligible for renegotiation.
100 State elgible(const Mode mode, const State state)
101 {
102 // Bit positions for Encrypt/Decrypt and Green/Red
103 enum
104 {
105 EG = 1 << 0,
106 ER = 1 << 1,
107 DG = 1 << 2,
108 DR = 1 << 3,
109 };
110 if (state > None)
111 {
112 const unsigned int mask = 1 << ((int(state) - 1) + (int(mode) << 1));
113 if (!(flags & mask))
114 {
115 flags |= mask;
116 if ((mask & (ER | DG)) && ((flags & (ER | DG)) == (ER | DG)))
117 return Red;
118 else if (mask & ER)
119 return None;
120 else
121 return state;
122 }
123 }
124 return None;
125 }
126
128 {
129 public:
130 Component(const size_type red_limit_arg)
131 : red_limit(red_limit_arg)
132 {
133 }
134
136 {
137 bytes += n;
139 }
140
141 State update_state(const State newstate)
142 {
143 State ret = None;
144 if (newstate > state)
145 state = ret = newstate;
146 return ret;
147 }
148
150 {
151 return state;
152 }
153
154 private:
156 {
157 switch (s)
158 {
159 case None:
160 if (bytes)
161 return Green;
162 else
163 return None;
164 case Green:
165 if (red_limit && bytes >= red_limit)
166 return Red;
167 else
168 return None;
169 case Red:
170 default:
171 return None;
172 }
173 }
174
178 };
179
181 {
182 switch (m)
183 {
184 case Encrypt:
185 return encrypt;
186 case Decrypt:
187 return decrypt;
188 default:
189 throw Exception("DataLimit::Component: unknown mode");
190 }
191 }
192
195 unsigned int flags = 0;
196};
197} // namespace openvpn
198
199#endif
State add(const size_type n)
Component(const size_type red_limit_arg)
State update_state(const State newstate)
State transition(State s) const
unsigned int size_type
Definition datalimit.hpp:25
State elgible(const Mode mode, const State state)
State add(const Mode mode, const size_type n)
Definition datalimit.hpp:57
DataLimit(const Parameters &p)
Definition datalimit.hpp:46
State update_state(const Mode mode, const State newstate)
Definition datalimit.hpp:52
static const char * mode_str(const Mode m)
Definition datalimit.hpp:67
static const char * state_str(const State s)
Definition datalimit.hpp:80
unsigned int flags
Component & component(const Mode m)
std::string ret