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 using size_type = unsigned int;
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 if (mask & ER)
119 return None;
120 return state;
121 }
122 }
123 return None;
124 }
125
127 {
128 public:
129 Component(const size_type red_limit_arg)
130 : red_limit(red_limit_arg)
131 {
132 }
133
135 {
136 bytes += n;
138 }
139
140 State update_state(const State newstate)
141 {
142 State ret = None;
143 if (newstate > state)
144 state = ret = newstate;
145 return ret;
146 }
147
149 {
150 return state;
151 }
152
153 private:
155 {
156 switch (s)
157 {
158 case None:
159 if (bytes)
160 return Green;
161 else
162 return None;
163 case Green:
164 if (red_limit && bytes >= red_limit)
165 return Red;
166 else
167 return None;
168 case Red:
169 default:
170 return None;
171 }
172 }
173
177 };
178
180 {
181 switch (m)
182 {
183 case Encrypt:
184 return encrypt;
185 case Decrypt:
186 return decrypt;
187 default:
188 throw Exception("DataLimit::Component: unknown mode");
189 }
190 }
191
194 unsigned int flags = 0;
195};
196} // namespace openvpn
197
198#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
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
unsigned int size_type
Definition datalimit.hpp:25
Component & component(const Mode m)
std::string ret