Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 1 | /* |
| 2 | Copyright (C) 2006-2009 Werner Dittmann |
| 3 | |
| 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by |
| 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 _ZRTPQUEUE_H_ |
| 19 | #define _ZRTPQUEUE_H_ |
| 20 | |
| 21 | #include <ccrtp/cqueue.h> |
| 22 | #include <ccrtp/rtppkt.h> |
| 23 | #include <libzrtpcpp/ZrtpCallback.h> |
| 24 | #include <libzrtpcpp/ZrtpConfigure.h> |
| 25 | #include <CcrtpTimeoutProvider.h> |
| 26 | |
| 27 | class __EXPORT ZrtpUserCallback; |
| 28 | class __EXPORT ZRtp; |
| 29 | |
| 30 | NAMESPACE_COMMONCPP |
| 31 | |
| 32 | /** |
| 33 | * GNU ccRTP extension to support GNU ZRTP. |
| 34 | * |
| 35 | * ZRTP was developed by Phil Zimmermann and provides functions to |
| 36 | * negotiate keys and other necessary data (crypto data) to set-up |
| 37 | * the Secure RTP (SRTP) crypto context. Refer to Phil's ZRTP |
| 38 | * specification at his <a href="http://zfoneproject.com/">Zfone |
| 39 | * project</a> site to get more detailed imformation about the |
| 40 | * capabilities of ZRTP. |
| 41 | * |
| 42 | * <b>Short overview of the ZRTP implementation</b> |
| 43 | * |
| 44 | * ZRTP is a specific protocol to negotiate encryption algorithms |
| 45 | * and the required key material. ZRTP uses a RTP session to |
| 46 | * exchange its protocol messages. |
| 47 | * |
| 48 | * A complete GNU ZRTP implementation consists of two parts, the |
| 49 | * GNU ZRTP core and specific code that binds the GNU ZRTP core to |
| 50 | * the underlying RTP/SRTP stack and the operating system: |
| 51 | * <ul> |
| 52 | * <li> |
| 53 | * The GNU ZRTP core is independent of a specific RTP/SRTP |
| 54 | * stack and the operationg system and consists of the ZRTP |
| 55 | * protocol state engine, the ZRTP protocol messages, and the |
| 56 | * GNU ZRTP engine. The GNU ZRTP engine provides methods to |
| 57 | * setup ZRTP message and to analyze received ZRTP messages, |
| 58 | * to compute the crypto data required for SRTP, and to |
| 59 | * maintain the required hashes and HMAC. |
| 60 | * </li> |
| 61 | * <li> |
| 62 | * The second part of an implementation is specific |
| 63 | * <em>glue</em> code the binds the GNU ZRTP core to the |
| 64 | * actual RTP/SRTP implementation and other operating system |
| 65 | * specific services such as timers. |
| 66 | * </li> |
| 67 | * </ul> |
| 68 | * |
| 69 | * The GNU ZRTP core uses a callback interface class (refer to |
| 70 | * ZrtpCallback) to access RTP/SRTP or operating specific methods, |
| 71 | * for example to send data via the RTP/SRTP stack, to access |
| 72 | * timers, provide mutex handling, and to report events to the |
| 73 | * application. |
| 74 | * |
| 75 | * <b>The ZrtpQueue</b> |
| 76 | * |
| 77 | * ZrtpQueue implements code that is specific to the GNU ccRTP |
| 78 | * implementation. ZrtpQueue also implements the specific code to |
| 79 | * provide the mutex and timeout handling to the GNU ZRTP |
| 80 | * core. Both, the mutex and the timeout handling, use the GNU |
| 81 | * Common C++ library to stay independent of the operating |
| 82 | * seystem. For more information refer to the <a |
| 83 | * href="http://www.gnutelephony.org/index.php/GNU_Common_C%2B%2B">GNU |
| 84 | * Common C++</a> web site. |
| 85 | * |
| 86 | * To perform its tasks ZrtpQueue |
| 87 | * <ul> |
| 88 | * <li> extends GNU ccRTP classes to use the underlying |
| 89 | * ccRTP methods and the RTP/SRTP send and receive queues |
| 90 | * </li> |
| 91 | * <li> implements the ZrtpCallback interface to provide ccRTP |
| 92 | * access and other specific services (timer, mutex) to GNU |
| 93 | * ZRTP |
| 94 | * </li> |
| 95 | * <li> provides ZRTP specific methods that applications may use |
| 96 | * to control and setup GNU ZRTP |
| 97 | * </li> |
| 98 | * <li> can register and use an application specific callback |
| 99 | * class (refer to ZrtpUserCallback) |
| 100 | * </li> |
| 101 | * </ul> |
| 102 | * |
| 103 | * After instantiating a GNU ZRTP session (see below for a short |
| 104 | * example) applications may use the ZRTP specific methods of |
| 105 | * ZrtpQueue to control and setup GNU ZRTP, for example enable or |
| 106 | * disable ZRTP processing or getting ZRTP status information. |
| 107 | * |
| 108 | * GNU ZRTP provides a ZrtpUserCallback class that an application |
| 109 | * may extend and register with ZrtpQueue. GNU ZRTP and ZrtpQueue |
| 110 | * use the ZrtpUserCallback methods to report ZRTP events to the |
| 111 | * application. The application may display this information to |
| 112 | * the user or act otherwise. |
| 113 | * |
| 114 | * The following figure depicts the relationships between |
| 115 | * ZrtpQueue, ccRTP RTP/SRTP implementation, the GNU ZRTP core, |
| 116 | * and an application that provides an ZrtpUserCallback class. |
| 117 | * |
| 118 | @verbatim |
| 119 | |
| 120 | +----------+ |
| 121 | | ccRTP | |
| 122 | | RTP/SRTP | |
| 123 | | | |
| 124 | +----------+ |
| 125 | ^ |
| 126 | | extends |
| 127 | | |
| 128 | +----------------+ +-----+------+ |
| 129 | | Application | | | +-----------------+ |
| 130 | | instantiates | uses | ZrtpQueue | uses | | |
| 131 | | a ZRTP Session +------+ implements +------+ GNU ZRTP | |
| 132 | | and provides | |ZrtpCallback| | core | |
| 133 | |ZrtpUserCallback| | | | implementation | |
| 134 | +----------------+ +------------+ | (ZRtp et al) | |
| 135 | | | |
| 136 | +-----------------+ |
| 137 | @endverbatim |
| 138 | * |
| 139 | * Because ZrtpQueue extends the ccRTP RTP/SRTP implementation |
| 140 | * (AVPQueue) all public methods defined by ccRTP are also |
| 141 | * available for a ZRTP session. ZrtpQueue overwrites some of the |
| 142 | * public methods of ccRTP (AVPQueue) to implement ZRTP specific |
| 143 | * code. |
| 144 | * |
| 145 | * GNU ZRTP provides a <em>SymmetricZRTPSession</em> type to |
| 146 | * simplify its use. An application uses this type in the same way |
| 147 | * as it would use the normal ccRTP <em>SymmetricRTPSession</em> |
| 148 | * type. The following short code snippets show how an application |
| 149 | * could instantiate ccRTP and GNU ZRTP sessions. The first |
| 150 | * snippet shows how to instantiate a ccRTP session: |
| 151 | * |
| 152 | * @code |
| 153 | * ... |
| 154 | * #include <ccrtp/rtp.h> |
| 155 | * ... |
| 156 | * SymmetricRTPSession tx(pattern.getSsrc(), |
| 157 | * InetHostAddress("localhost")); |
| 158 | * ... |
| 159 | * |
| 160 | * @endcode |
| 161 | * |
| 162 | * The same code as above but using a GNU ZRTP session this time: |
| 163 | * @code |
| 164 | * ... |
| 165 | * #include <libzrtpcpp/zrtpccrtp.h> |
| 166 | * ... |
| 167 | * SymmetricZRTPSession tx(pattern.getSsrc(), |
| 168 | * InetHostAddress("localhost")); |
| 169 | * ... |
| 170 | * |
| 171 | * @endcode |
| 172 | * |
| 173 | * The only differences are the different include statements and |
| 174 | * the different session types. |
| 175 | * |
| 176 | * The <em>demo</em> folder contains a small example that shows |
| 177 | * how to use GNU ZRTP. |
| 178 | * |
| 179 | * Please refer to the GNU ccRTP documentation for a description |
| 180 | * of ccRTP methods and functions. This ZrtpQueue documentation |
| 181 | * shows the ZRTP specific extensions and describes overloaded |
| 182 | * methods and a possible different behaviour. |
| 183 | * |
| 184 | * @author Werner Dittmann <Werner.Dittmann@t-online.de> |
| 185 | */ |
| 186 | |
| 187 | class __EXPORT ZrtpQueue : public AVPQueue, ZrtpCallback { |
| 188 | |
| 189 | public: |
| 190 | |
| 191 | /** |
| 192 | * Initialize the ZrtpQueue. |
| 193 | * |
| 194 | * Before an application can use ZRTP it has to initialize the |
| 195 | * ZRTP implementation. This method initializes the timeout |
| 196 | * thread and opens a file that contains ZRTP specific |
| 197 | * information such as the applications ZID (ZRTP id) and its |
| 198 | * retained shared secrets. |
| 199 | * |
| 200 | * If one application requires several ZRTP sessions all |
| 201 | * sessions use the same timeout thread and use the same ZID |
| 202 | * file. Therefore an application does not need to do any |
| 203 | * synchronisation regading ZID files or timeouts. This is |
| 204 | * managed by the ZRTP implementation. |
| 205 | * |
| 206 | * The current implementation of ZrtpQueue does not support |
| 207 | * different ZID files for one application instance. This |
| 208 | * restriction may be removed in later versions. |
| 209 | * |
| 210 | * The application may specify its own ZID file name. If no |
| 211 | * ZID file name is specified it defaults to |
| 212 | * <code>$HOME/.GNUccRTP.zid</code> if the <code>HOME</code> |
| 213 | * environment variable is set. If it is not set the current |
| 214 | * directory is used. |
| 215 | * |
| 216 | * If the method could set up the timeout thread and open the ZID |
| 217 | * file then it enables ZRTP processing and returns. |
| 218 | * |
| 219 | * @param zidFilename |
| 220 | * The name of the ZID file, can be a relative or absolut |
| 221 | * filename. |
| 222 | * |
| 223 | * @param autoEnable |
| 224 | * if set to true the method automatically sets enableZrtp to |
| 225 | * true. This enables the ZRTP auto-sense mode. Default is true. |
| 226 | * |
| 227 | * @param config |
| 228 | * this parameter points to ZRTP configuration data. If it is |
| 229 | * NULL then ZrtpQueue uses a default setting. Default is NULL. |
| 230 | * |
| 231 | * @return |
| 232 | * 1 on success, ZRTP processing enabled, -1 on failure, |
| 233 | * ZRTP processing disabled. |
| 234 | * |
| 235 | */ |
| 236 | int32_t initialize(const char *zidFilename, bool autoEnable = true, |
| 237 | ZrtpConfigure* config = NULL); |
| 238 | |
| 239 | /* |
| 240 | * Applications use the following methods to control ZRTP, for example |
| 241 | * to enable ZRTP, set flags etc. |
| 242 | */ |
| 243 | |
| 244 | /** |
| 245 | * Enable or disable ZRTP processing. |
| 246 | * |
| 247 | * Call this method to enable or disable ZRTP processing after |
| 248 | * calling <code>initialize()</code>. This can be done before |
| 249 | * using a RTP session or at any time during a RTP session. |
| 250 | * |
| 251 | * Existing SRTP sessions or currently active ZRTP processing will |
| 252 | * not be stopped or disconnected. |
| 253 | * |
| 254 | * If the application enables ZRTP then: |
| 255 | * <ul> |
| 256 | * <li>ZrtpQueue starts to send ZRTP Hello packets after at least |
| 257 | * one RTP packet was sent and received on the associated RTP |
| 258 | * session. Thus if an application enables ZRTP and ZrtpQueue |
| 259 | * detects traffic on the RTP session then ZrtpQueue automatically |
| 260 | * starts the ZRTP protocol. This automatic start is convenient |
| 261 | * for applications that negotiate RTP parameters and set up RTP |
| 262 | * sessions but the actual RTP traffic starts some time later. |
| 263 | * </li> |
| 264 | * <li>ZrtpQueue analyses incoming packets to detect ZRTP |
| 265 | * messages. If ZRTP was started, either via automatic start (see |
| 266 | * above) or explicitly via startZrtp(), then ZrtpQueue |
| 267 | * forwards ZRTP packets to the GNU ZRTP core. |
| 268 | * </ul> |
| 269 | * |
| 270 | * @param onOff |
| 271 | * @c true to enable ZRTP, @c false to disable ZRTP |
| 272 | */ |
| 273 | void setEnableZrtp(bool onOff); |
| 274 | |
| 275 | /** |
| 276 | * Return the state of ZRTP enable state. |
| 277 | * |
| 278 | * @return @c true if ZRTP processing is enabled, @c false |
| 279 | * otherwise. |
| 280 | */ |
| 281 | bool isEnableZrtp(); |
| 282 | |
| 283 | /** |
| 284 | * Set SAS as verified. |
| 285 | * |
| 286 | * The application may call this method if the user confirmed |
| 287 | * (verfied) the Short Authentication String (SAS) with the peer. |
| 288 | * |
| 289 | * ZRTP calls ZrtpUserCallback#showSAS after it computed the SAS |
| 290 | * and the application registered a user callback class. The |
| 291 | * application should display the SAS and provide a mechanism at |
| 292 | * the user interface that enables the user to confirm the SAS. |
| 293 | * |
| 294 | * ZRTP remembers the SAS confirmation status together with the |
| 295 | * retained secrets data. If both parties confirmed the SAS then |
| 296 | * ZRTP informs the application about this status on the next ZRTP |
| 297 | * session. |
| 298 | * |
| 299 | * For more detailed information regarding SAS please refer to the |
| 300 | * ZRTP specification, chapter 8. |
| 301 | */ |
| 302 | void SASVerified(); |
| 303 | |
| 304 | /** |
| 305 | * Reset the SAS verfied flag for the current user's retained secrets. |
| 306 | * |
| 307 | */ |
| 308 | void resetSASVerified(); |
| 309 | |
| 310 | /** |
| 311 | * To confirm a go clear request. |
| 312 | * |
| 313 | * Call this method if the user confirmed a go clear (secure mode off). |
| 314 | */ |
| 315 | void goClearOk(); |
| 316 | |
| 317 | /** |
| 318 | * Request to switch off secure mode. |
| 319 | * |
| 320 | * Call this method is the user itself wants to switch off secure |
| 321 | * mode (go clear). After sending the "go clear" request to the peer |
| 322 | * ZRTP immediatly switch off SRTP processing. Every RTP data is sent |
| 323 | * in clear after the go clear request. |
| 324 | */ |
| 325 | void requestGoClear(); |
| 326 | |
| 327 | /** |
| 328 | * Set the auxilliary secret. |
| 329 | * |
| 330 | * Use this method to set the srtps secret data. Refer to ZRTP |
| 331 | * specification, chapter 5.3 ff |
| 332 | * |
| 333 | * @param data |
| 334 | * Points to the auxilliary secret data. |
| 335 | * @param length |
| 336 | * Length of the auxilliary secrect in bytes |
| 337 | */ |
| 338 | void setAuxSecret(uint8_t* data, int32_t length); |
| 339 | |
| 340 | /** |
| 341 | * Set the application's callback class. |
| 342 | * |
| 343 | * The destructor of ZrtpQueue also destorys the user callback |
| 344 | * class if it was set. The application must not delete the |
| 345 | * callback object or use/reference the callback object after |
| 346 | * ZrtpQueue was destroyed. |
| 347 | * |
| 348 | * @param ucb |
| 349 | * Implementation of the application's ZrtpUserCallback class |
| 350 | */ |
| 351 | void setUserCallback(ZrtpUserCallback* ucb); |
| 352 | |
| 353 | /** |
| 354 | * Set the client ID for ZRTP Hello message. |
| 355 | * |
| 356 | * The GNU ccRTP client may set its id to identify itself in the |
| 357 | * ZRTP Hello message. The maximum length is 16 characters. A |
| 358 | * shorter id string is possible, it will be filled with blanks. A |
| 359 | * longer id string will be truncated to 16 characters. The |
| 360 | * standard client id is <code>'GNU ccRTP ZRTP '</code> (without |
| 361 | * the quotes). |
| 362 | * |
| 363 | * Setting the client's id must be done before calling |
| 364 | * ZrtpQueue#initialize() or ZrtpQueue#startZrtp() . |
| 365 | * |
| 366 | * @param id |
| 367 | * The client's id string |
| 368 | */ |
| 369 | void setClientId(std::string id); |
| 370 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 371 | /** |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 372 | * Get the ZRTP Hello Hash data. |
| 373 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 374 | * Use this method to get the ZRTP Hello hash data. The method |
| 375 | * returns the data as a string containing the ZRTP protocol version and |
| 376 | * hex-digits. |
| 377 | * |
| 378 | * The index defines which Hello packet to use. Each supported ZRTP procol version |
| 379 | * uses a different Hello packet and thus computes different hashes. |
| 380 | * |
| 381 | * Refer to ZRTP specification, chapter 8. |
| 382 | * |
| 383 | * @param index |
| 384 | * Hello hash of the Hello packet identfied by index. Index must be 0 <= index < getNumberSupportedVersions(). |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 385 | * |
| 386 | * @return |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 387 | * a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:' |
| 388 | * SDP attribute identifier. The hello hash is available immediatly after class instantiation. |
| 389 | * |
| 390 | * @see getNumberSupportedVersions() |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 391 | */ |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 392 | std::string getHelloHash(int32_t index); |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 393 | |
| 394 | /** |
| 395 | * Get the peer's ZRTP Hello Hash data. |
| 396 | * |
| 397 | * Use this method to get the peer's ZRTP Hello Hash data. The method |
| 398 | * returns the data as a string containing the ZRTP protocol version and |
| 399 | * hex-digits. |
| 400 | * |
| 401 | * The peer's hello hash is available only after ZRTP received a hello. If |
| 402 | * no data is available the function returns an empty string. |
| 403 | * |
| 404 | * Refer to ZRTP specification, chapter 8. |
| 405 | * |
| 406 | * @return |
| 407 | * a std:string containing the Hello version and the hello hash as hex digits. |
| 408 | */ |
| 409 | std::string getPeerHelloHash(); |
| 410 | |
| 411 | /** |
| 412 | * Get Multi-stream parameters. |
| 413 | * |
| 414 | * Use this method to get the Multi-stream that were computed during |
| 415 | * the ZRTP handshake. An application may use these parameters to |
| 416 | * enable multi-stream processing for an associated SRTP session. |
| 417 | * |
| 418 | * Refer to chapter 5.4.2 in the ZRTP specification for further details |
| 419 | * and restriction how and when to use multi-stream mode. |
| 420 | * |
| 421 | * @return |
| 422 | * a string that contains the multi-stream parameters. The application |
| 423 | * must not modify the contents of this string, it is opaque data. The |
| 424 | * application may hand over this string to a new ZrtpQueue instance |
| 425 | * to enable multi-stream processing for this ZrtpQueue. If ZRTP was |
| 426 | * not started or ZRTP is not yet in secure state the method returns an |
| 427 | * empty string. |
| 428 | * |
| 429 | * @see setMultiStrParams() |
| 430 | */ |
| 431 | std::string getMultiStrParams(); |
| 432 | |
| 433 | /** |
| 434 | * Set Multi-stream parameters. |
| 435 | * |
| 436 | * Use this method to set the parameters required to enable Multi-stream |
| 437 | * processing of ZRTP. The multi-stream parameters must be set before the |
| 438 | * application starts the ZRTP protocol engine. |
| 439 | * |
| 440 | * Refer to chapter 5.4.2 in the ZRTP specification for further details |
| 441 | * of multi-stream mode. |
| 442 | * |
| 443 | * @param parameters |
| 444 | * A string that contains the multi-stream parameters that this |
| 445 | * new ZrtpQueue instanace shall use. |
| 446 | * |
| 447 | * @see getMultiStrParams() |
| 448 | */ |
| 449 | void setMultiStrParams(std::string parameters); |
| 450 | |
| 451 | /** |
| 452 | * Check if this ZRTP use Multi-stream. |
| 453 | * |
| 454 | * Use this method to check if this ZRTP instance uses multi-stream. Even |
| 455 | * if the application provided multi-stram parameters it may happen that |
| 456 | * full DH mode was used. Refer to chapters 5.2 and 5.4.2 in the ZRTP # |
| 457 | * when this may happen. |
| 458 | * |
| 459 | * @return |
| 460 | * True if multi-stream is used, false otherwise. |
| 461 | */ |
| 462 | bool isMultiStream(); |
| 463 | |
| 464 | /** |
| 465 | * Check if the other ZRTP client supports Multi-stream. |
| 466 | * |
| 467 | * Use this method to check if the other ZRTP client supports |
| 468 | * Multi-stream mode. |
| 469 | * |
| 470 | * @return |
| 471 | * True if multi-stream is available, false otherwise. |
| 472 | */ |
| 473 | bool isMultiStreamAvailable(); |
| 474 | |
| 475 | /** |
| 476 | * Accept a PBX enrollment request. |
| 477 | * |
| 478 | * If a PBX service asks to enroll the MiTM key and the user accepts this |
| 479 | * requtes, for example by pressing an OK button, the client application |
| 480 | * shall call this method and set the parameter <code>accepted</code> to |
| 481 | * true. If the user does not accept the request set the parameter to |
| 482 | * false. |
| 483 | * |
| 484 | * @param accepted |
| 485 | * True if the enrollment request is accepted, false otherwise. |
| 486 | */ |
| 487 | void acceptEnrollment(bool accepted); |
| 488 | |
| 489 | /** |
| 490 | * Get the commited SAS rendering algorithm for this ZRTP session. |
| 491 | * |
| 492 | * @return the commited SAS rendering algorithm |
| 493 | */ |
| 494 | std::string getSasType(); |
| 495 | |
| 496 | /** |
| 497 | * Get the computed SAS hash for this ZRTP session. |
| 498 | * |
| 499 | * A PBX ZRTP back-to-Back function uses this function to get the SAS |
| 500 | * hash of an enrolled client to construct the SAS relay packet for |
| 501 | * the other client. |
| 502 | * |
| 503 | * @return a refernce to the byte array that contains the full |
| 504 | * SAS hash. |
| 505 | */ |
| 506 | uint8_t* getSasHash(); |
| 507 | |
| 508 | /** |
| 509 | * Send the SAS relay packet. |
| 510 | * |
| 511 | * The method creates and sends a SAS relay packet according to the ZRTP |
| 512 | * specifications. Usually only a MitM capable user agent (PBX) uses this |
| 513 | * function. |
| 514 | * |
| 515 | * @param sh the full SAS hash value |
| 516 | * @param render the SAS rendering algorithm |
| 517 | */ |
| 518 | bool sendSASRelayPacket(uint8_t* sh, std::string render); |
| 519 | |
| 520 | /** |
| 521 | * Check the state of the MitM mode flag. |
| 522 | * |
| 523 | * If true then this ZRTP session acts as MitM, usually enabled by a PBX |
| 524 | * client (user agent) |
| 525 | * |
| 526 | * @return state of mitmMode |
| 527 | */ |
| 528 | bool isMitmMode(); |
| 529 | |
| 530 | /** |
| 531 | * Set the state of the MitM mode flag. |
| 532 | * |
| 533 | * If MitM mode is set to true this ZRTP session acts as MitM, usually |
| 534 | * enabled by a PBX client (user agent). |
| 535 | * |
| 536 | * @param mitmMode defines the new state of the mitmMode flag |
| 537 | */ |
| 538 | void setMitmMode(bool mitmMode); |
| 539 | |
| 540 | /** |
| 541 | * Enable or disable paranoid mode. |
| 542 | * |
| 543 | * The Paranoid mode controls the behaviour and handling of the SAS verify flag. If |
| 544 | * Panaoid mode is set to flase then ZRtp applies the normal handling. If Paranoid |
| 545 | * mode is set to true then the handling is: |
| 546 | * |
| 547 | * <ul> |
| 548 | * <li> always set the SAS verify flag to <code>false</code> at srtpSecretsOn() callback. The |
| 549 | * user interface (UI) must show <b>SAS not verified</b>. See implementation note below.</li> |
| 550 | * <li> don't set the SAS verify flag in the <code>Confirm</code> packets, thus forcing the other |
| 551 | * peer to report <b>SAS not verified</b>.</li> |
| 552 | * <li> ignore the <code>SASVerified()</code> function, thus do not set the SAS verified flag |
| 553 | * in the ZRTP cache. </li> |
| 554 | * <li> Disable the <em>Trusted PBX MitM</em> feature. Just send the <code>SASRelay</code> packet |
| 555 | * but do not process the relayed data. This protects the user from a malicious |
| 556 | * "trusted PBX".</li> |
| 557 | * </ul> |
| 558 | * ZRtp performs alls other steps during the ZRTP negotiations as usual, in particular it |
| 559 | * computes, compares, uses, and stores the retained secrets. This avoids unnecessary warning |
| 560 | * messages. The user may enable or disable the Paranoid mode on a call-by-call basis without |
| 561 | * breaking the key continuity data. |
| 562 | * |
| 563 | * <b>Implementation note:</b><br/> |
| 564 | * An application shall <b>always display the SAS if the SAS verify flag is <code>false</code></b>. |
| 565 | * The application shall remind the user to compare the SAS code, for example using larger fonts, |
| 566 | * different colours and other display features. |
| 567 | */ |
| 568 | void setParanoidMode(bool yesNo); |
| 569 | |
| 570 | /** |
| 571 | * Check status of paranoid mode. |
| 572 | * |
| 573 | * @return |
| 574 | * Returns true if paranoid mode is enabled. |
| 575 | */ |
| 576 | bool isParanoidMode(); |
| 577 | |
| 578 | /** |
| 579 | * Check the state of the enrollment mode. |
| 580 | * |
| 581 | * If true then we will set the enrollment flag (E) in the confirm |
| 582 | * packets and performs the enrollment actions. A MitM (PBX) enrollment service sets this flagstarted this ZRTP |
| 583 | * session. Can be set to true only if mitmMode is also true. |
| 584 | * @return status of the enrollmentMode flag. |
| 585 | */ |
| 586 | bool isEnrollmentMode(); |
| 587 | |
| 588 | /** |
| 589 | * Check the state of the enrollment mode. |
| 590 | * |
| 591 | * If true then we will set the enrollment flag (E) in the confirm |
| 592 | * packets and perform the enrollment actions. A MitM (PBX) enrollment |
| 593 | * service must sets this mode to true. |
| 594 | * |
| 595 | * Can be set to true only if mitmMode is also true. |
| 596 | * |
| 597 | * @param enrollmentMode defines the new state of the enrollmentMode flag |
| 598 | */ |
| 599 | void setEnrollmentMode(bool enrollmentMode); |
| 600 | |
| 601 | /** |
| 602 | * Check if a peer's cache entry has a vaild MitM key. |
| 603 | * |
| 604 | * If true then the other peer ha a valid MtiM key, i.e. the peer has performed |
| 605 | * the enrollment procedure. A PBX ZRTP Back-2-Back application can use this function |
| 606 | * to check which of the peers is enrolled. |
| 607 | * |
| 608 | * @return True if the other peer has a valid Mitm key (is enrolled). |
| 609 | */ |
| 610 | bool isPeerEnrolled(); |
| 611 | |
| 612 | /** |
| 613 | * Set the state of the SAS signature mode flag. |
| 614 | * |
| 615 | * If SAS signature mode is set to true this ZRTP session support SAS signature |
| 616 | * callbacks and signature transfer between clients. |
| 617 | * |
| 618 | * @param sasSignMode defines the new state of the sasSignMode flag |
| 619 | */ |
| 620 | void setSignSas(bool sasSignMode); |
| 621 | |
| 622 | /** |
| 623 | * Set signature data |
| 624 | * |
| 625 | * This functions stores signature data and transmitts it during ZRTP |
| 626 | * processing to the other party as part of the Confirm packets. Refer to |
| 627 | * chapters 6.7 and 8.2 in the ZRTP specification. |
| 628 | * |
| 629 | * @param data |
| 630 | * The signature data including the signature type block. The method |
| 631 | * copies this data into the Confirm packet at signature type block. |
| 632 | * @param length |
| 633 | * The length of the signature data in bytes. This length must be |
| 634 | * multiple of 4. |
| 635 | * @return |
| 636 | * True if the method stored the data, false otherwise. |
| 637 | */ |
| 638 | bool setSignatureData(uint8* data, int32 length); |
| 639 | |
| 640 | /** |
| 641 | * Get signature data |
| 642 | * |
| 643 | * This functions returns signature data that was receivied during ZRTP |
| 644 | * processing. Refer to chapters 6.7 and 8.2. |
| 645 | * |
| 646 | * @return |
| 647 | * Pointer to signature data. This is a pointer to volatile data that is |
| 648 | * only valid during the checkSASSignature() callback. The application |
| 649 | * shall copy the data if necessary. |
| 650 | */ |
| 651 | const uint8* getSignatureData(); |
| 652 | |
| 653 | /** |
| 654 | * Get length of signature data |
| 655 | * |
| 656 | * This functions returns the length of signature data that was receivied |
| 657 | * during ZRTP processing. Refer to chapters 6.7 and 8.2. |
| 658 | * |
| 659 | * @return |
| 660 | * Length in bytes of the received signature data. The method returns |
| 661 | * zero if no signature data avilable. |
| 662 | */ |
| 663 | int32 getSignatureLength(); |
| 664 | |
| 665 | /** |
| 666 | * Put data into the RTP output queue. |
| 667 | * |
| 668 | * This is used to create a data packet in the send queue. |
| 669 | * Sometimes a "NULL" or empty packet will be used instead, and |
| 670 | * these are known as "silent" packets. "Silent" packets are |
| 671 | * used simply to "push" the scheduler along more accurately |
| 672 | * by giving the appearence that a next packet is waiting to |
| 673 | * be sent and to provide a valid timestamp for that packet. |
| 674 | * |
| 675 | * This method overrides the same method in OutgoingDataQueue class. |
| 676 | * During ZRTP processing it may be necessary to control the |
| 677 | * flow of outgoing RTP payload packets (GoClear processing). |
| 678 | * |
| 679 | * @param stamp Timestamp for expected send time of packet. |
| 680 | * @param data Value or NULL if special "silent" packet. |
| 681 | * @param len May be 0 to indicate a default by payload type. |
| 682 | **/ |
| 683 | void |
| 684 | putData(uint32 stamp, const unsigned char* data = NULL, size_t len = 0); |
| 685 | |
| 686 | /** |
| 687 | * Immediatly send a data packet. |
| 688 | * |
| 689 | * This is used to create a data packet and send it immediately. |
| 690 | * Sometimes a "NULL" or empty packet will be used instead, and |
| 691 | * these are known as "silent" packets. "Silent" packets are |
| 692 | * used simply to "push" the scheduler along more accurately |
| 693 | * by giving the appearence that a next packet is waiting to |
| 694 | * be sent and to provide a valid timestamp for that packet. |
| 695 | * |
| 696 | * This method overrides the same method in OutgoingDataQueue |
| 697 | * class. During ZRTP processing it may be necessary to |
| 698 | * control the flow of outgoing RTP payload packets (GoClear |
| 699 | * processing). |
| 700 | * |
| 701 | * @param stamp Timestamp immediate send time of packet. |
| 702 | * @param data Value or NULL if special "silent" packet. |
| 703 | * @param len May be 0 to indicate a default by payload type. |
| 704 | **/ |
| 705 | void |
| 706 | sendImmediate(uint32 stamp, const unsigned char* data = NULL, size_t len = 0); |
| 707 | |
| 708 | /** |
| 709 | * Starts the ZRTP protocol engine. |
| 710 | * |
| 711 | * Applications may call this method to immediatly start the ZRTP protocol |
| 712 | * engine any time after initializing ZRTP and setting optinal parameters, |
| 713 | * for example client id or multi-stream parameters. |
| 714 | * |
| 715 | * If the application does not call this method but sucessfully initialized |
| 716 | * the ZRTP engine using <code>initialize()</code> then ZRTP also starts |
| 717 | * after the application sent and received RTP packets. An application can |
| 718 | * disable this automatic, delayed start of the ZRTP engine using |
| 719 | * <code>setEnableZrtp(false)</code> before sending or receiving RTP |
| 720 | * packets. |
| 721 | * |
| 722 | */ |
| 723 | void startZrtp(); |
| 724 | |
| 725 | /** |
| 726 | * Stops the ZRTP protocol engine. |
| 727 | * |
| 728 | * Applications call this method to stop the ZRTP protocol |
| 729 | * engine. |
| 730 | * |
| 731 | */ |
| 732 | void stopZrtp(); |
| 733 | |
| 734 | /** |
| 735 | * Get other party's ZID (ZRTP Identifier) data |
| 736 | * |
| 737 | * This functions returns the other party's ZID that was receivied |
| 738 | * during ZRTP processing. |
| 739 | * |
| 740 | * The ZID data can be retrieved after ZRTP receive the first Hello |
| 741 | * packet from the other party. The application may call this method |
| 742 | * for example during SAS processing in showSAS(...) user callback |
| 743 | * method. |
| 744 | * |
| 745 | * @param data |
| 746 | * Pointer to a data buffer. This buffer must have a size of |
| 747 | * at least 12 bytes (96 bit) (ZRTP Identifier, see chap. 4.9) |
| 748 | * @return |
| 749 | * Number of bytes copied into the data buffer - must be equivalent |
| 750 | * to 96 bit, usually 12 bytes. |
| 751 | */ |
| 752 | int32 getPeerZid(uint8* data); |
| 753 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 754 | /** |
| 755 | * Get number of supported ZRTP protocol versions. |
| 756 | * |
| 757 | * @return the number of supported ZRTP protocol versions. |
| 758 | */ |
| 759 | int32_t getNumberSupportedVersions(); |
| 760 | |
| 761 | /** |
| 762 | * Get negotiated ZRTP protocol version. |
| 763 | * |
| 764 | * @return the integer representation of the negotiated ZRTP protocol version. |
| 765 | */ |
| 766 | int32_t getCurrentProtocolVersion(); |
| 767 | |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 768 | protected: |
| 769 | friend class TimeoutProvider<std::string, ost::ZrtpQueue*>; |
| 770 | |
| 771 | /** |
| 772 | * A hook that gets called if the decoding of an incoming SRTP |
| 773 | * was erroneous |
| 774 | * |
| 775 | * @param pkt |
| 776 | * The SRTP packet with error. |
| 777 | * @param errorCode |
| 778 | * The error code: -1 - SRTP authentication failure, -2 - replay |
| 779 | * check failed |
| 780 | * @return |
| 781 | * True: put the packet in incoming queue for further processing |
| 782 | * by the applications; false: dismiss packet. The default |
| 783 | * implementation returns false. |
| 784 | */ |
| 785 | virtual bool |
| 786 | onSRTPPacketError(IncomingRTPPkt& pkt, int32 errorCode); |
| 787 | |
| 788 | /** |
| 789 | * Handle timeout event forwarded by the TimeoutProvider. |
| 790 | * |
| 791 | * Just call the ZRTP engine for further processing. |
| 792 | */ |
| 793 | void handleTimeout(const std::string &c); |
| 794 | |
| 795 | /** |
| 796 | * This function is used by the service thread to process |
| 797 | * the next incoming packet and place it in the receive list. |
| 798 | * |
| 799 | * This class overloads the function of IncomingDataQueue |
| 800 | * implementation. |
| 801 | * |
| 802 | * @return number of payload bytes received, <0 if error. |
| 803 | */ |
| 804 | virtual size_t takeInDataPacket(); |
| 805 | |
| 806 | /* |
| 807 | * The following methods implement the GNU ZRTP callback interface. |
| 808 | * For detailed documentation refer to file ZrtpCallback.h |
| 809 | */ |
| 810 | int32_t sendDataZRTP(const unsigned char* data, int32_t length); |
| 811 | |
| 812 | int32_t activateTimer(int32_t time); |
| 813 | |
| 814 | int32_t cancelTimer(); |
| 815 | |
| 816 | void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode); |
| 817 | |
| 818 | bool srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part); |
| 819 | |
| 820 | void srtpSecretsOff(EnableSecurity part); |
| 821 | |
| 822 | void srtpSecretsOn(std::string c, std::string s, bool verified); |
| 823 | |
| 824 | void handleGoClear(); |
| 825 | |
| 826 | void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode); |
| 827 | |
| 828 | void zrtpNotSuppOther(); |
| 829 | |
| 830 | void synchEnter(); |
| 831 | |
| 832 | void synchLeave(); |
| 833 | |
| 834 | void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info); |
| 835 | |
| 836 | void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info); |
| 837 | |
| 838 | void signSAS(uint8_t* sasHash); |
| 839 | |
| 840 | bool checkSASSignature(uint8_t* sasHash); |
| 841 | |
| 842 | /* |
| 843 | * End of ZrtpCallback functions. |
| 844 | */ |
| 845 | |
| 846 | ZrtpQueue(uint32 size = RTPDataQueue::defaultMembersHashSize, |
| 847 | RTPApplication& app = defaultApplication()); |
| 848 | |
| 849 | /** |
| 850 | * Local SSRC is given instead of computed by the queue. |
| 851 | */ |
| 852 | ZrtpQueue(uint32 ssrc, uint32 size = |
| 853 | RTPDataQueue::defaultMembersHashSize, |
| 854 | RTPApplication& app = defaultApplication()); |
| 855 | |
| 856 | virtual ~ZrtpQueue(); |
| 857 | |
| 858 | private: |
| 859 | void init(); |
| 860 | size_t rtpDataPacket(unsigned char* packet, int32 rtn, |
| 861 | InetHostAddress network_address, |
| 862 | tpport_t transport_port); |
| 863 | |
| 864 | ZRtp *zrtpEngine; |
| 865 | ZrtpUserCallback* zrtpUserCallback; |
| 866 | |
| 867 | std::string clientIdString; |
| 868 | |
| 869 | bool enableZrtp; |
| 870 | |
| 871 | int32 secureParts; |
| 872 | |
| 873 | int16 senderZrtpSeqNo; |
| 874 | ost::Mutex synchLock; // Mutex for ZRTP (used by ZrtpStateClass) |
| 875 | uint32 peerSSRC; |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 876 | uint64 zrtpUnprotect; |
Alexandre Lision | ddd731e | 2014-01-31 11:50:08 -0500 | [diff] [blame] | 877 | bool started; |
| 878 | bool mitmMode; |
| 879 | bool signSas; |
| 880 | bool enableParanoidMode; |
| 881 | }; |
| 882 | |
| 883 | class IncomingZRTPPkt : public IncomingRTPPkt { |
| 884 | |
| 885 | public: |
| 886 | /** |
| 887 | * Build a ZRTP packet object from a data buffer. |
| 888 | * |
| 889 | * @param block pointer to the buffer the whole packet is stored in. |
| 890 | * @param len length of the whole packet, expressed in octets. |
| 891 | * |
| 892 | **/ |
| 893 | |
| 894 | IncomingZRTPPkt(const unsigned char* block, size_t len); |
| 895 | |
| 896 | ~IncomingZRTPPkt() |
| 897 | { } |
| 898 | |
| 899 | uint32 |
| 900 | getZrtpMagic() const; |
| 901 | |
| 902 | uint32 |
| 903 | getSSRC() const; |
| 904 | }; |
| 905 | |
| 906 | class OutgoingZRTPPkt : public OutgoingRTPPkt { |
| 907 | |
| 908 | public: |
| 909 | /** |
| 910 | * Construct a new ZRTP packet to be sent. |
| 911 | * |
| 912 | * A new copy in memory (holding all this components |
| 913 | * along with the fixed header) is created. |
| 914 | * |
| 915 | * @param hdrext whole header extension. |
| 916 | * @param hdrextlen size of whole header extension, in octets. |
| 917 | **/ |
| 918 | OutgoingZRTPPkt(const unsigned char* const hdrext, uint32 hdrextlen); |
| 919 | ~OutgoingZRTPPkt() |
| 920 | { } |
| 921 | }; |
| 922 | |
| 923 | END_NAMESPACE |
| 924 | |
| 925 | #endif |
| 926 | |
| 927 | /** EMACS ** |
| 928 | * Local variables: |
| 929 | * mode: c++ |
| 930 | * c-default-style: ellemtel |
| 931 | * c-basic-offset: 4 |
| 932 | * End: |
| 933 | */ |
| 934 | |