Alexandre Lision | 51140e1 | 2013-12-02 10:54:09 -0500 | [diff] [blame] | 1 | /* |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame] | 2 | Copyright (C) 2006-2013 Werner Dittmann |
Alexandre Lision | 51140e1 | 2013-12-02 10:54:09 -0500 | [diff] [blame] | 3 | |
| 4 | This program is free software: you can redistribute it and/or modify |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame] | 5 | it under the terms of the GNU Lesser General Public License as published by |
Alexandre Lision | 51140e1 | 2013-12-02 10:54:09 -0500 | [diff] [blame] | 6 | the Free Software Foundation, either version 3 of the License, or |
| 7 | (at your option) any later version. |
| 8 | |
| 9 | This program is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | |
| 18 | #ifndef _ZRTPSTATECLASS_H_ |
| 19 | #define _ZRTPSTATECLASS_H_ |
| 20 | |
| 21 | /** |
| 22 | * @file ZrtpStateClass.h |
| 23 | * @brief The ZRTP state handling class |
| 24 | * |
| 25 | * @ingroup GNU_ZRTP |
| 26 | * @{ |
| 27 | */ |
| 28 | |
| 29 | #include <libzrtpcpp/ZrtpStates.h> |
| 30 | #include <libzrtpcpp/ZrtpPacketBase.h> |
| 31 | |
| 32 | /** |
| 33 | * The ZRTP states |
| 34 | * |
| 35 | * Depending on the role of this state engine and the actual protocl flow |
| 36 | * not all states are processed during a ZRTP handshake. |
| 37 | */ |
| 38 | enum zrtpStates { |
| 39 | Initial, ///< Initial state after starting the state engine |
| 40 | Detect, ///< State sending Hello, try to detect answer message |
| 41 | AckDetected, ///< HelloAck received |
| 42 | AckSent, ///< HelloAck sent after Hello received |
| 43 | WaitCommit, ///< Wait for a Commit message |
| 44 | CommitSent, ///< Commit message sent |
| 45 | WaitDHPart2, ///< Wait for a DHPart2 message |
| 46 | WaitConfirm1, ///< Wait for a Confirm1 message |
| 47 | WaitConfirm2, ///< Wait for a confirm2 message |
| 48 | WaitConfAck, ///< Wait for Conf2Ack |
| 49 | WaitClearAck, ///< Wait for clearAck - not used |
| 50 | SecureState, ///< This is the secure state - SRTP active |
| 51 | WaitErrorAck, ///< Wait for ErrorAck message |
| 52 | numberOfStates ///< Gives total number of protocol states |
| 53 | }; |
| 54 | |
| 55 | enum EventReturnCodes { |
| 56 | Fail = 0, ///< ZRTP event processing failed. |
| 57 | Done = 1 ///< Event processing ok. |
| 58 | }; |
| 59 | |
| 60 | enum EventDataType { |
| 61 | ZrtpInitial = 1, ///< Initial event, enter Initial state |
| 62 | ZrtpClose, ///< Close event, shut down state engine |
| 63 | ZrtpPacket, ///< Normal ZRTP message event, process according to state |
| 64 | Timer, ///< Timer event |
| 65 | ErrorPkt ///< Error packet event |
| 66 | }; |
| 67 | |
| 68 | enum SecureSubStates { |
| 69 | Normal, |
| 70 | WaitSasRelayAck, |
| 71 | numberofSecureSubStates |
| 72 | }; |
| 73 | |
| 74 | /// A ZRTP state event |
| 75 | typedef struct Event { |
| 76 | EventDataType type; ///< Type of event |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 77 | size_t length; ///< length of the message data |
Alexandre Lision | 51140e1 | 2013-12-02 10:54:09 -0500 | [diff] [blame] | 78 | uint8_t* packet; ///< Event data if availabe, usually a ZRTP message |
| 79 | } Event_t; |
| 80 | |
| 81 | |
| 82 | /** |
| 83 | * The ZRTP timer structure. |
| 84 | * |
| 85 | * This structure holds all necessary data to compute the timer for |
| 86 | * the protocol timers. The state engine allocate one structure for |
| 87 | * each timer. ZRTP uses two timers, T1 and T2, to monitor protocol |
| 88 | * timeouts. As a slight misuse but to make overall handling a bit |
| 89 | * simpler this structure also contains the resend counter. This is |
| 90 | * possible in ZRTP because it uses a simple timeout strategy. |
| 91 | */ |
| 92 | typedef struct zrtpTimer { |
| 93 | int32_t time, ///< Current timeout value |
| 94 | start, ///< Start value for timeout |
| 95 | increment, ///< increment timeout after each timeout event (not used anymore) |
| 96 | capping, ///< Maximum timeout value |
| 97 | counter, ///< Current number of timeouts |
| 98 | maxResend; ///< Maximum number of timeout resends |
| 99 | } zrtpTimer_t; |
| 100 | |
| 101 | |
| 102 | class ZRtp; |
| 103 | |
| 104 | /** |
| 105 | * This class is the ZRTP protocol state engine. |
| 106 | * |
| 107 | * This class is responsible to handle the ZRTP protocol. It does not |
| 108 | * handle the ZRTP HMAC, DH, and other data management. This is done in |
| 109 | * class ZRtp, which is the parent of this class. |
| 110 | * |
| 111 | * The methods of this class implement the ZRTP state actions. |
| 112 | * |
| 113 | */ |
| 114 | |
| 115 | |
| 116 | class __EXPORT ZrtpStateClass { |
| 117 | |
| 118 | private: |
| 119 | ZRtp* parent; ///< The ZRTP implmentation |
| 120 | ZrtpStates* engine; ///< The state switching engine |
| 121 | Event_t* event; ///< Current event to process |
| 122 | |
| 123 | /** |
| 124 | * The last packet that was sent. |
| 125 | * |
| 126 | * If we are <code>Initiator</code> then resend this packet in case of |
| 127 | * timeout. |
| 128 | */ |
| 129 | ZrtpPacketBase* sentPacket; |
| 130 | |
| 131 | /** |
| 132 | * Points to prepared Commit packet after receiving a Hello packet |
| 133 | */ |
| 134 | ZrtpPacketCommit* commitPkt; |
| 135 | |
| 136 | zrtpTimer_t T1; ///< The Hello message timeout timer |
| 137 | zrtpTimer_t T2; ///< Timeout timer for other messages |
| 138 | |
| 139 | /* |
| 140 | * If this is set to true the protocol engine handle the multi-stream |
| 141 | * variant of ZRTP. Refer to chapter 5.4.2 in the ZRTP specification. |
| 142 | */ |
| 143 | bool multiStream; |
| 144 | |
| 145 | // Secure substate to handle SAS relay packets |
| 146 | SecureSubStates secSubstate; |
| 147 | |
| 148 | /** |
| 149 | * Secure Sub state WaitSasRelayAck. |
| 150 | * |
| 151 | * This state belongs to the secure substates and handles |
| 152 | * SAS Relay Ack. |
| 153 | * |
| 154 | * When entering this transition function |
| 155 | * - sentPacket contains Error packet, Error timer active |
| 156 | * |
| 157 | * Possible events in this state are: |
| 158 | * - timeout for sent SAS Relay packet: causes a resend check and repeat sending |
| 159 | * of packet |
| 160 | * - SASRelayAck: Stop timer and switch to secure substate Normal. |
| 161 | */ |
| 162 | bool subEvWaitRelayAck(); |
| 163 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame] | 164 | /** |
| 165 | * Hello packet version sent to other partner |
| 166 | */ |
| 167 | int32_t sentVersion; |
| 168 | |
Alexandre Lision | 51140e1 | 2013-12-02 10:54:09 -0500 | [diff] [blame] | 169 | public: |
| 170 | /// Create a ZrtpStateClass |
| 171 | ZrtpStateClass(ZRtp *p); |
| 172 | ~ZrtpStateClass(); |
| 173 | |
| 174 | /// Check if in a specified state |
| 175 | bool inState(const int32_t state) { return engine->inState(state); }; |
| 176 | |
| 177 | /// Switch to the specified state |
| 178 | void nextState(int32_t state) { engine->nextState(state); }; |
| 179 | |
| 180 | /// Process an event, the main entry point into the state engine |
| 181 | void processEvent(Event_t *ev); |
| 182 | |
| 183 | /** |
| 184 | * The state event handling methods. |
| 185 | * |
| 186 | * Refer to the protocol state diagram for further documentation. |
| 187 | */ |
| 188 | /// Initial event state |
| 189 | void evInitial(); |
| 190 | |
| 191 | /// Detect state |
| 192 | void evDetect(); |
| 193 | |
| 194 | /// HelloAck detected state |
| 195 | void evAckDetected(); |
| 196 | |
| 197 | /// HelloAck sent state |
| 198 | void evAckSent(); |
| 199 | |
| 200 | /// Wait for Commit message |
| 201 | void evWaitCommit(); |
| 202 | |
| 203 | /// Commit sent state |
| 204 | void evCommitSent(); |
| 205 | |
| 206 | /// Wait for DHPart2 message |
| 207 | void evWaitDHPart2(); |
| 208 | |
| 209 | /// Wait for Confirm2 message |
| 210 | void evWaitConfirm1(); |
| 211 | |
| 212 | /// Wait for Confirm2 message |
| 213 | void evWaitConfirm2(); |
| 214 | |
| 215 | /// Wait for ConfAck message |
| 216 | void evWaitConfAck(); |
| 217 | |
| 218 | /// Wait for ClearAck message (not used) |
| 219 | void evWaitClearAck(); |
| 220 | |
| 221 | /// Secure reached state |
| 222 | void evSecureState(); |
| 223 | |
| 224 | /// Wait for ErrorAck message |
| 225 | void evWaitErrorAck(); |
| 226 | |
| 227 | /** |
| 228 | * Initialize and activate a timer. |
| 229 | * |
| 230 | * @param t |
| 231 | * The ZRTP timer structure to use for the timer. |
| 232 | * @return |
| 233 | * 1 timer was activated |
| 234 | * 0 activation failed |
| 235 | */ |
| 236 | int32_t startTimer(zrtpTimer_t *t); |
| 237 | |
| 238 | /** |
| 239 | * Compute and set the next timeout value. |
| 240 | * |
| 241 | * @param t |
| 242 | * The ZRTP timer structure to use for the timer. |
| 243 | * @return |
| 244 | * 1 timer was activated |
| 245 | * 0 activation failed |
| 246 | * -1 resend counter exceeded |
| 247 | */ |
| 248 | int32_t nextTimer(zrtpTimer_t *t); |
| 249 | |
| 250 | /** |
| 251 | * Cancel the active timer. |
| 252 | * |
| 253 | * @return |
| 254 | * 1 timer was canceled |
| 255 | * 0 cancelation failed |
| 256 | */ |
| 257 | int32_t cancelTimer() {return parent->cancelTimer(); }; |
| 258 | |
| 259 | /** |
| 260 | * Prepare and send an Error packet. |
| 261 | * |
| 262 | * Preparse an Error packet and sends it. It stores the Error |
| 263 | * packet in the sentPacket variable to enable resending. The |
| 264 | * method switches to protocol state Initial. |
| 265 | */ |
| 266 | void sendErrorPacket(uint32_t errorCode); |
| 267 | |
| 268 | /** |
| 269 | * Set status if an error occured while sending a ZRTP packet. |
| 270 | * |
| 271 | * This functions clears data and set the state to Initial after the engine |
| 272 | * detected a problem while sending a ZRTP packet. |
| 273 | * |
| 274 | * @return |
| 275 | * Fail code |
| 276 | */ |
| 277 | void sendFailed(); |
| 278 | |
| 279 | /** |
| 280 | * Set status if a timer problems occure. |
| 281 | * |
| 282 | * This functions clears data and set state to Initial after a timer |
| 283 | * error occured. Either no timer available or resend counter exceedeed. |
| 284 | * |
| 285 | * @return |
| 286 | * Fail code |
| 287 | */ |
| 288 | void timerFailed(int32_t subCode); |
| 289 | |
| 290 | /** |
| 291 | * Set multi-stream mode flag. |
| 292 | * |
| 293 | * This functions set the multi-stream mode. The protocol |
| 294 | * engine will run the multi-stream mode variant of the ZRTP |
| 295 | * protocol if this flag is set to true. |
| 296 | * |
| 297 | * @param multi |
| 298 | * Set the multi-stream mode flag to true or false. |
| 299 | */ |
| 300 | void setMultiStream(bool multi); |
| 301 | |
| 302 | /** |
| 303 | * Status of multi-stream mode flag. |
| 304 | * |
| 305 | * This functions returns the value of the multi-stream mode flag. |
| 306 | * |
| 307 | * @return |
| 308 | * Value of the multi-stream mode flag. |
| 309 | */ |
| 310 | bool isMultiStream(); |
| 311 | |
| 312 | /** |
| 313 | * Send a SAS relay packet. |
| 314 | * |
| 315 | * the functions stores sends the SAS relay packet and stores the pointer in |
| 316 | * the sentPacket variable to enable resending. |
| 317 | * |
| 318 | * The method switches to secure substate WaitSasRelayAck. |
| 319 | * |
| 320 | * @param relay |
| 321 | * Pointer to the SAS relay packet. |
| 322 | */ |
| 323 | void sendSASRelay(ZrtpPacketSASrelay* relay); |
| 324 | }; |
| 325 | |
| 326 | /** |
| 327 | * @} |
| 328 | */ |
| 329 | #endif // _ZRTPSTATECLASS_H_ |
| 330 | |