Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 1 | /* |
| 2 | Copyright (C) 2012-2013 Werner Dittmann |
| 3 | |
| 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser 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 _ZRTPSDESSTREAM_H_ |
| 19 | #define _ZRTPSDESSTREAM_H_ |
| 20 | /** |
| 21 | * @file ZrtpSdesStream.h |
| 22 | * @brief The ZRTP main engine |
| 23 | * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation |
| 24 | * @{ |
| 25 | * |
| 26 | * This class implements SDES and provides a simple to use API for applications. |
| 27 | * |
| 28 | * This SDES implementation currently supports only two SDES algorithms and it does |
| 29 | * not support optional parameters such as lifetime or MKI parameters. Also session |
| 30 | * parameters are not supported. Most applications that use SDES don't use these |
| 31 | * optional parameters. |
| 32 | * |
| 33 | * It is not necessary to explicitly start the SDES stream. The class initiates |
| 34 | * the SRTP after it created and parsed all necessary SDES crypto strings. |
| 35 | * |
| 36 | * Because SDES works together with the signaling protocol, for example SIP, it is |
| 37 | * important to adhere to a defined flow. The following pseudo code snippet depicts |
| 38 | * such a flow. Applications shall follow this flow. |
| 39 | * |
| 40 | *<pre> |
| 41 | * |
| 42 | * Inviter Answerer |
| 43 | * (Offerer) |
| 44 | * |
| 45 | * ZrtpSdesStream inv; ZrtpSdesStream answ; |
| 46 | * |
| 47 | * // create/get own SDES data |
| 48 | * inv.createSdes(...); |
| 49 | * inv.getCryptoMixAttribute(...) |
| 50 | * |
| 51 | * // prepare SIP/SDP offer, send |
| 52 | * // it to answerer |
| 53 | * // receive SIP/SDP, get |
| 54 | * // SDES data, parse/set it |
| 55 | * answ.setCryptoMixAttribute(...) |
| 56 | * answ.parseSdes(...) |
| 57 | * |
| 58 | * // create/get own SDES data |
| 59 | * answ.getCryptoMixAttribute(...) |
| 60 | * answ.createSdes(...) |
| 61 | * |
| 62 | * // prepare SIP/SDP answer, |
| 63 | * // send to offerer |
| 64 | * // receive SIP/SDP answer, get |
| 65 | * // SDES data, parse, set mix algo |
| 66 | * // if availabe |
| 67 | * inv.setCryptoMixAttribute(...) |
| 68 | * inv.parseSdes(...) |
| 69 | * |
| 70 | * ... ... |
| 71 | * |
| 72 | * inv.outgoingRtp(...) |
| 73 | * answ.incomingRtp(...) |
| 74 | * |
| 75 | * answ.outgoingRtp(...) |
| 76 | * inv.incomingRtp(...) |
| 77 | *</pre> |
| 78 | * |
| 79 | * To use SDES without the new crypto mix feature just do not use the crypto mix functions. |
| 80 | * An application may always send crypto mix attributes. If the answerer does not support this |
| 81 | * feature it does not send back a selected algorithm and the offerer cannot set an algorithm. |
| 82 | * Thus the crypto mix feature is not used. |
| 83 | * |
| 84 | * @author Werner Dittmann <Werner.Dittmann@t-online.de> |
| 85 | */ |
| 86 | |
| 87 | #include <common/osSpecifics.h> |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 88 | |
| 89 | class CryptoContext; |
| 90 | class CryptoContextCtrl; |
| 91 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 92 | /* |
| 93 | * These functions support 256 bit encryption algorithms. |
| 94 | */ |
| 95 | #define MAX_KEY_LEN 32 |
| 96 | #define MAX_SALT_LEN 14 |
| 97 | #define MAX_DIGEST_LENGTH 64 |
| 98 | |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 99 | /** |
| 100 | * Maximum length of a raw crypto string. |
| 101 | */ |
| 102 | #define MAX_CRYPT_STRING_LEN 200 |
| 103 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 104 | class __EXPORT ZrtpSdesStream { |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 105 | |
| 106 | public: |
| 107 | |
| 108 | /** |
| 109 | * Supported SDES crypto suites. |
| 110 | */ |
| 111 | typedef enum { |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 112 | AES_CM_128_HMAC_SHA1_32 = 0, |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 113 | AES_CM_128_HMAC_SHA1_80 |
| 114 | } sdesSuites; |
| 115 | |
| 116 | /** |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 117 | * SDES stream state |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 118 | */ |
| 119 | typedef enum { |
| 120 | STREAM_INITALIZED = 1, |
| 121 | OUT_PROFILE_READY, |
| 122 | IN_PROFILE_READY, |
| 123 | SDES_SRTP_ACTIVE |
| 124 | } sdesZrtpStates; |
| 125 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 126 | typedef enum { |
| 127 | MIX_NONE = 0, |
| 128 | MIX_HMAC_SHA, |
| 129 | MIX_MAC_SKEIN |
| 130 | } sdesHmacTypeMix; |
| 131 | |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 132 | /** |
| 133 | * @brief Create and SDES/ZRTP stream. |
| 134 | * |
| 135 | * This method creates an SDES stream with capabilities to handle RTP, |
| 136 | * RTCP, SRTP, and SRTCP packets. |
| 137 | * |
| 138 | * @param suite defines which crypto suite to use for this stream. The values are |
| 139 | * @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32. |
| 140 | */ |
| 141 | ZrtpSdesStream(const sdesSuites suite =AES_CM_128_HMAC_SHA1_32); |
| 142 | |
| 143 | ~ZrtpSdesStream(); |
| 144 | |
| 145 | /** |
| 146 | * @brief Close an SDES/ZRTP stream. |
| 147 | * |
| 148 | * Close the stream and return allocated memory to the pool. |
| 149 | */ |
| 150 | void close(); |
| 151 | |
| 152 | /** |
| 153 | * @brief Creates an SDES crypto string for the SDES/ZRTP stream. |
| 154 | * |
| 155 | * Creates the crypto string that the application can use in the SDP fields of |
| 156 | * SIP INVITE or SIP 200 OK. |
| 157 | * |
| 158 | * An INVITE-ing application shall call this function at the same point when |
| 159 | * it calls the functions to get the @c zrtp-hash string and shall insert the |
| 160 | * created crypto string into the SDP. |
| 161 | * |
| 162 | * An answering application shall call this function directly @b after it called |
| 163 | * @c sdesZrtpStreamParseSdes. This usually at the same point when it gets the |
| 164 | * @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The |
| 165 | * answering application's SRTP environment is now ready. |
| 166 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 167 | * @param cryptoString output buffer that receives the crypto string in raw |
| 168 | * format, without the any signaling prefix, for example |
| 169 | * @c a=crypto:. The function terminates the crypto string |
| 170 | * with a @c nul byte |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 171 | * |
| 172 | * @param maxLen length of the crypto string buffer. On return it contains the |
| 173 | * actual length of the crypto string. |
| 174 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 175 | * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must |
| 176 | * set it to @c false. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 177 | * |
| 178 | * @return @c true if data could be created, @c false otherwise. |
| 179 | */ |
| 180 | bool createSdes(char *cryptoString, size_t *maxLen, bool sipInvite); |
| 181 | |
| 182 | /** |
| 183 | * @brief Parses an SDES crypto string for the SDES/ZRTP stream. |
| 184 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 185 | * Parses a SDES crypto string that the application received in a SIP INVITE |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 186 | * or SIP 200 OK. |
| 187 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 188 | * An INVITE-ing (offerer) application shall call this function right after it received |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 189 | * the 200 OK from the answering application and must call this function with the |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 190 | * @c sipInvite parameter set to @c true. The offerer's SRTP is now ready for use. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 191 | * |
| 192 | * The answering application calls this function after it received the INVITE and |
| 193 | * extracted the crypto string from the SDP and must call this function with the |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 194 | * @c sipInvite parameter set to @c false. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 195 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 196 | * @param cryptoString the received crypto sting in raw format, |
| 197 | * without any signaling prefix, for example @c a=crypto: |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 198 | * |
| 199 | * @param length length of the crypto string to parse. If the length is |
| 200 | * @c zero then the function uses @c strlen to compute |
| 201 | * the length. |
| 202 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 203 | * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must |
| 204 | * set it to @c false. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 205 | * |
| 206 | * @return @c true if data could be created, @c false otherwise. |
| 207 | */ |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 208 | bool parseSdes(const char *cryptoString, size_t length, bool sipInvite); |
| 209 | |
| 210 | /** |
| 211 | * @brief Get Crypto Mix attribute string |
| 212 | * |
| 213 | * The offerer calls this method to get a string of @b all supported crypto mix algorithms |
| 214 | * and shall send this list to the answerer. |
| 215 | * |
| 216 | * The answerer calls this function only @b after it received the crypto mix string and @b after |
| 217 | * calling @c setCryptoMixAttribute(...). The method returns only one (the selected) |
| 218 | * crypto mix algorithm and the answerer must send this to the offerer, for example in 200 OK. |
| 219 | * |
| 220 | * @param algoNames buffer to store the nul terminated crypto mix algorithm names. |
| 221 | * The buffer must be long enough to hold at least the name of the mandatory |
| 222 | * algorithm HMAC-SHA-384. |
| 223 | * |
| 224 | * @param length length of buffer |
| 225 | * |
| 226 | * @return Length of algorithm names (excluding nul byte) or zero if crypto mix not supported or |
| 227 | * enabled. |
| 228 | */ |
| 229 | int getCryptoMixAttribute(char *algoNames, size_t length); |
| 230 | |
| 231 | /** |
| 232 | * @brief Set Crypto Mix attribute string |
| 233 | * |
| 234 | * The method checks if it the string contains an supported algorithm and selects one algorithm. |
| 235 | * |
| 236 | * The offerer calls this method @b after it received the selected algorithm in the answer. |
| 237 | * |
| 238 | * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method. |
| 239 | * |
| 240 | * @param algoNames buffer that contains the received crypto mix algorithm names. |
| 241 | * The buffer must be nul terminated. |
| 242 | * |
| 243 | * @return @c false if none of the offered algorithms is supported. |
| 244 | */ |
| 245 | bool setCryptoMixAttribute(const char *algoNames); |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 246 | |
| 247 | /* |
| 248 | * ******** Outgoing RTP/RTCP packet handling |
| 249 | */ |
| 250 | /** |
| 251 | * @brief Process an outgoing RTP packet |
| 252 | * |
| 253 | * This function processes an outgoing RTP packet. Depending on the state |
| 254 | * the packet is either: |
| 255 | * - not encrypted if neither SDES nor ZRTP are active or supported by the |
| 256 | * other client. This is the standard case if the stream was just initialized. |
| 257 | * - encrypted with SDES provided key data. This is the case if the application |
| 258 | * called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes |
| 259 | * functions to properly setup the SDES key data. |
| 260 | * |
| 261 | * @param packet the buffer that contains the RTP packet. After processing, the |
| 262 | * encrypted packet is stored in the same buffer. The buffer must |
| 263 | * big enough to hold the additional SRTP data, depending on the |
| 264 | * SRTP profile these are usually 4 - 20 bytes. |
| 265 | * |
| 266 | * @param length length of the RTP packet |
| 267 | * |
| 268 | * @param newLength to an integer that get the new length of the packet including SRTP data. |
| 269 | * |
| 270 | * @return |
| 271 | * - @c true if encryption is successful, app shall send packet to the recipient. |
| 272 | * - @c false if there was an error during encryption, don't send the packet. |
| 273 | */ |
| 274 | bool outgoingRtp(uint8_t *packet, size_t length, size_t *newLength); |
| 275 | |
| 276 | /** |
| 277 | * @brief Process an outgoing RTCP packet |
| 278 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 279 | * This function works in the same way as @c outgoingRtp. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 280 | * |
| 281 | * @param packet the buffer that contains the RTCP packet. After processing, the |
| 282 | * encrypted packet is stored in the same buffer. The buffer must |
| 283 | * big enough to hold the additional SRTP data, depending on the |
| 284 | * SRTP profile these are usually 8 - 20 bytes. |
| 285 | * |
| 286 | * @param length length of the RTP packet |
| 287 | * |
| 288 | * @param newLength to an integer that get the new length of the packet including SRTP data. |
| 289 | * |
| 290 | * @return |
| 291 | * - @c true if encryption is successful, app shall send packet to the recipient. |
| 292 | * - @c false if there was an error during encryption, don't send the packet. |
| 293 | */ |
| 294 | bool outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength); |
| 295 | |
| 296 | /* |
| 297 | * ******** Incoming SRTP/SRTCP packet handling |
| 298 | */ |
| 299 | /** |
| 300 | * @brief Process an incoming RTP or SRTP packet |
| 301 | * |
| 302 | * This function processes an incoming RTP/SRTP packet. Depending on the state |
| 303 | * the packet is either: |
| 304 | * - not decrypted if SDES is not active or supported by the |
| 305 | * other client. This is the standard case if the stream was just initialized. |
| 306 | * - decrypted with SDES provided key data. This is the case if the application |
| 307 | * called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes |
| 308 | * functions to properly setup the SDES key data. |
| 309 | * |
| 310 | * @param packet the buffer that contains the RTP/SRTP packet. After processing, |
| 311 | * the decrypted packet is stored in the same buffer. |
| 312 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 313 | * @param length length of the RTP packet |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 314 | * |
| 315 | * @param newLength to an integer that get the new length of the packet excluding SRTCP data. |
| 316 | * |
| 317 | * @return |
| 318 | * - 1: success, |
| 319 | * - -1: SRTP authentication failed, |
| 320 | * - -2: SRTP replay check failed |
| 321 | */ |
| 322 | int incomingRtp(uint8_t *packet, size_t length, size_t *newLength); |
| 323 | |
| 324 | /** |
| 325 | * @brief Process an incoming RTCP or SRTCP packet |
| 326 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 327 | * This function works in the same way as @c incomingRtp. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 328 | * |
| 329 | * @param packet the buffer that contains the RTCP/SRTCP packet. After processing, |
| 330 | * the decrypted packet is stored in the same buffer. |
| 331 | * |
| 332 | * @param length length of the RTCP packet |
| 333 | * |
| 334 | * @param newLength to an integer that get the new length of the packet excluding SRTCP data. |
| 335 | * |
| 336 | * @return |
| 337 | * - 1: success, |
| 338 | * - -1: SRTCP authentication failed, |
| 339 | * - -2: SRTCP replay check failed |
| 340 | */ |
| 341 | int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength); |
| 342 | |
| 343 | /** |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 344 | * @brief Process an outgoing ZRTP packet. |
| 345 | * |
| 346 | * Works like @c outgoingRtp, refer to that documentation. |
| 347 | * |
| 348 | * @param packet the buffer that contains the ZRTP packet. |
| 349 | * |
| 350 | * @param length length of the ZRTP packet |
| 351 | * |
| 352 | * @param newLength to an integer that get the new length of the packet including SRTP data. |
| 353 | * |
| 354 | * @return |
| 355 | * - @c true if encryption is successful, app shall send packet to the recipient. |
| 356 | * - @c false if there was an error during encryption, don't send the packet. |
| 357 | */ |
| 358 | bool outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength); |
| 359 | |
| 360 | /** |
| 361 | * @brief Process an incoming ZRTP packet |
| 362 | * |
| 363 | * Works like @c incomingRtp, refer to that documentation. |
| 364 | * |
| 365 | * @param packet the buffer that contains the ZRTP/SRTP packet. After processing, |
| 366 | * the decrypted packet is stored in the same buffer. |
| 367 | * |
| 368 | * @param length length of the RTP packet |
| 369 | * |
| 370 | * @param newLength to an integer that get the new length of the packet excluding SRTCP data. |
| 371 | * |
| 372 | * @return |
| 373 | * - 1: success, |
| 374 | * - -1: SRTP authentication failed, |
| 375 | * - -2: SRTP replay check failed |
| 376 | */ |
| 377 | int incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength); |
| 378 | |
| 379 | /** |
| 380 | * @brief Return state of SDES stream. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 381 | * |
| 382 | * @return state of stream. |
| 383 | */ |
| 384 | sdesZrtpStates getState() {return state;} |
| 385 | |
| 386 | /** |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 387 | * @brief Return SDES crypto mixer HMAC type. |
| 388 | * |
| 389 | * @return HMAC type |
| 390 | */ |
| 391 | sdesHmacTypeMix getHmacTypeMix() {return cryptoMixHashType;} |
| 392 | |
| 393 | /** |
| 394 | * @brief Return name of active cipher algorithm. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 395 | * |
| 396 | * @return point to name of cipher algorithm. |
| 397 | */ |
| 398 | const char* getCipher(); |
| 399 | |
| 400 | /** |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 401 | * @brief Return name of active SRTP authentication algorithm. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 402 | * |
| 403 | * @return point to name of authentication algorithm. |
| 404 | */ |
| 405 | const char* getAuthAlgo(); |
| 406 | |
| 407 | |
| 408 | /* |
| 409 | * ******** Lower layer functions |
| 410 | */ |
| 411 | private: |
| 412 | /** |
| 413 | * @brief Create an SRTP crypto context and the according SDES crypto string. |
| 414 | * |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 415 | * This lower layer method creates an SDES crypto string. It selects a valid |
| 416 | * crypto suite, generates the key and salt data, converts these into base 64 |
| 417 | * and returns the crypto string in raw format without any signaling prefixes. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 418 | * |
| 419 | * The output string has the following format: |
| 420 | * @verbatim |
| 421 | * 1 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj |
| 422 | * @endverbatim |
| 423 | * |
| 424 | * Applications usually don't use this method directly. Applications shall |
| 425 | * use the SDES stream functions. |
| 426 | * |
| 427 | * Depending on the crypto suite the overall length of the crypto string |
| 428 | * is variable. For a normal AES_128_CM suite the minumum lenth is 73 |
| 429 | * characters, a AES_256_CM suite results in 97 characters (not counting |
| 430 | * any signaling prefixes). |
| 431 | * |
| 432 | * @param cryptoString points to a char output buffer that receives the |
| 433 | * crypto string in the raw format, without the any |
| 434 | * signaling prefix, for example @c a=crypto: in case |
| 435 | * of SDP signaling. The function terminates the |
| 436 | * crypto string with a @c nul byte |
| 437 | * |
| 438 | * @param maxLen points to an integer. On input this integer specifies the |
| 439 | * length of the output buffer. If @c maxLen is smaller than |
| 440 | * the resulting crypto string the function returns an error |
| 441 | * conde. On return the functions sets @c maxLen to the |
| 442 | * actual length of the resultig crypto string. |
| 443 | * |
| 444 | * @param tag the value of the @c tag field in the crypto string. The |
| 445 | * answerer must use this input to make sure that the tag value |
| 446 | * in the answer matches the value in the offer. See RFC 4568, |
| 447 | * section 5.1.2. |
| 448 | * If the tag value is @c -1 the function sets the tag to @c 1. |
| 449 | * |
| 450 | * @return @c true if data could be created, @c false |
| 451 | * otherwise. |
| 452 | */ |
| 453 | bool createSdesProfile(char *cryptoString, size_t *maxLen); |
| 454 | |
| 455 | /** |
| 456 | * @brief Parse and check an offered SDES crypto string and create SRTP crypto context. |
| 457 | * |
| 458 | * The method parses an offered SDES crypto string and checks if it is |
| 459 | * valid. Next it checks if the string contains a supported crypto suite |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 460 | * and if the key and salt lengths match the selected crypto suite. |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 461 | * |
| 462 | * Applications usually don't use this method directly. Applications shall |
| 463 | * use the SDES stream functions. |
| 464 | * |
| 465 | * @b NOTE: This function does not support the optional parameters lifetime, |
| 466 | * MKI, and session parameters. While it can parse liftime and MKI theiy are |
| 467 | * not evaluated and used. If these parameters are used in the input crypto |
| 468 | * string the function return @c false. |
| 469 | * |
| 470 | * @param cryptoString points to the crypto sting in raw format, |
| 471 | * without any signaling prefix, for example @c a=crypto: in case of |
| 472 | * SDP signaling. |
| 473 | * |
| 474 | * @param length length of the crypto string to parse. If the length is |
| 475 | * @c zero then the function uses @c strlen to compute the length. |
| 476 | * |
| 477 | * @param parsedSuite the function sets this to the @c sdesSuites enumerator of |
| 478 | * the parsed crypto suite. The answerer shall use this as input to |
| 479 | * @c createSdesProfile to make sure that it creates the same crypto suite. |
| 480 | * See RFC 4568, section 5.1.2 |
| 481 | * |
| 482 | * @param tag the function sets this to the @c tag value of the parsed crypto |
| 483 | * string. The answerer must use this as input to @c createSdesProfile |
| 484 | * to make sure that it creates the correct tag in the crypto string. |
| 485 | * See RFC 4568, section 5.1.2 |
| 486 | * |
| 487 | * @return @c true if checks were ok, @c false |
| 488 | * otherwise. |
| 489 | */ |
| 490 | bool parseCreateSdesProfile(const char *cryptoString, size_t length, sdesSuites *parsedSuite, int32_t *tag); |
| 491 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 492 | /** |
| 493 | * @brief Create the SRTP contexts after all SDES creation and parsing is done. |
| 494 | * |
| 495 | * @param sipInvite if this is set to @c true (not zero) then the method |
| 496 | * computes the key data for the inviting SIP application (offerer) and |
| 497 | * for the answerer otherwise. |
| 498 | */ |
| 499 | void createSrtpContexts(bool sipInvite); |
| 500 | |
| 501 | /** |
| 502 | * @brief Compute the mixed keys if SDES mixing attribute is set. |
| 503 | * |
| 504 | * The method takes the parsed or created SDES key material and computes the mixed keys and salt. |
| 505 | * It replaces the existing key material with the new data. |
| 506 | * |
| 507 | * @param sipInvite if this is set to @c true (not zero) then the method |
| 508 | * computes the key data for the inviting SIP application (offerer) and |
| 509 | * for the answerer otherwise. |
| 510 | */ |
| 511 | void computeMixedKeys(bool sipInvite); |
| 512 | |
| 513 | |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 514 | sdesZrtpStates state; |
| 515 | sdesSuites suite; |
| 516 | int32_t tag; |
| 517 | CryptoContext *recvSrtp; //!< The SRTP context for this stream |
| 518 | CryptoContextCtrl *recvSrtcp; //!< The SRTCP context for this stream |
| 519 | CryptoContext *sendSrtp; //!< The SRTP context for this stream |
| 520 | CryptoContextCtrl *sendSrtcp; //!< The SRTCP context for this stream |
| 521 | uint32_t srtcpIndex; //!< the local SRTCP index |
| 522 | |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 523 | CryptoContext *recvZrtpTunnel; //!< The SRTP context for sender ZRTP tunnel |
| 524 | CryptoContext *sendZrtpTunnel; //!< The SRTP context for receiver ZRTP tunnel |
| 525 | |
| 526 | int32_t cryptoMixHashLength; |
| 527 | sdesHmacTypeMix cryptoMixHashType; |
| 528 | |
| 529 | // Variables for crypto that this client creates and sends to the other client, filled during SDES create |
| 530 | uint8_t localKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4]; //!< Some buffer for key and salt, multiple of 4 |
| 531 | int localKeyLenBytes; |
| 532 | int localSaltLenBytes; |
| 533 | int localCipher; |
| 534 | int localAuthn; |
| 535 | int localAuthKeyLen; |
| 536 | int localTagLength; |
| 537 | |
| 538 | // Variables for crypto that this client receives from the other client, filled during SDES parse |
| 539 | uint8_t remoteKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4]; //!< Some buffer for key and salt, multiple of 4 |
| 540 | int remoteKeyLenBytes; |
| 541 | int remoteSaltLenBytes; |
| 542 | int remoteCipher; |
| 543 | int remoteAuthn; |
| 544 | int remoteAuthKeyLen; |
| 545 | int remoteTagLength; |
Alexandre Lision | 7fd5d3d | 2013-12-04 13:06:40 -0500 | [diff] [blame] | 546 | }; |
Alexandre Lision | 907ed2e | 2014-02-04 10:33:09 -0500 | [diff] [blame^] | 547 | #endif |