blob: a9bb03f3d247ea42789020f0b12932914eee947e [file] [log] [blame]
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001/*
2 * Tivi client glue code for ZRTP.
3 * Copyright (c) 2012 Slient Circle LLC. All rights reserved.
4 *
5 *
6 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
7 */
8
9#ifndef _CTZRTPSTREAM_H_
10#define _CTZRTPSTREAM_H_
11
12#include <map>
13#include <vector>
14
15#include <libzrtpcpp/ZrtpCallback.h>
16#include <libzrtpcpp/ZrtpSdesStream.h>
17
18#include <CtZrtpSession.h>
19#include <TiviTimeoutProvider.h>
20
21// Define sizer of internal buffers.
22// NOTE: ZRTP buffer is large. An application shall never use ZRTP protocol
23// options that fully use it, otherwise IP packet fragmentation may happen.
24static const int maxZrtpSize = 3072;
25static const int maxSdesString = 256;
26
27static const uint32_t supressWarn = 200;
28static const uint32_t srtpErrorBurstThreshold = 20;
29
30class CryptoContext;
31class CryptoContextCtrl;
32class ZRtp;
33class CtZrtpCb;
34class CtZrtpSendCb;
35class CtZrtpSession;
36class ZrtpSdesStream;
37class CMutexClass;
38
39class __EXPORT CtZrtpStream: public ZrtpCallback {
40
41public:
42
43 CtZrtpSession::tiviStatus getCurrentState() {return tiviState;}
44
45 CtZrtpSession::tiviStatus getPreviousState() {return prevTiviState;}
46
47protected:
48
49 CtZrtpSession::streamName index; //!< either audio or video. Index in stream array
50 CtZrtpSession::streamType type; //!< Master or slave stream. Necessary to handle multi-stream
51 ZRtp *zrtpEngine; //!< The ZRTP core class of this stream
52 uint32_t ownSSRC; //!< Our own SSRC, in host order
53
54 uint64_t zrtpProtect;
55 uint64_t sdesProtect;
56
57 uint64_t zrtpUnprotect;
58 uint64_t sdesUnprotect;
59 uint64_t unprotectFailed;
60
61 bool enableZrtp; //!< Enable the streams ZRTP engine
62 bool started; //!< This stream's ZRTP engine is started
63 bool isStopped; //!< Stream stopped by Tivi
64 CtZrtpSession *session;
65
66 CtZrtpStream();
67 friend class CtZrtpSession;
68 friend class TimeoutProvider<std::string, CtZrtpStream*>;
69
70
71 virtual ~CtZrtpStream();
72 /**
73 * Handle timeout event forwarded by the TimeoutProvider.
74 *
75 * Just call the ZRTP engine for further processing.
76 */
77 void handleTimeout(const std::string &c);
78
79 /**
80 * Set the application's callback class.
81 *
82 * @param ucb
83 * Implementation of the application's callback class
84 */
85 void setUserCallback(CtZrtpCb* ucb);
86
87 /**
88 * Set the application's send data callback class.
89 *
90 *
91 * @param ucb
92 * Implementation of the application's send data callback class
93 */
94 void setSendCallback(CtZrtpSendCb* scb);
95
96 /**
97 * Stop this stream and reset internal variables to initial state.
98 *
99 */
100 void stopStream();
101
102 /**
103 * @brief Process outgoing data.
104 *
105 * Depending on the state of the buffer the functions either returns the buffer
106 * umodified or encrypted.
107 *
108 * The function takes a uint8_t buffer that must contain RTP packet data. The
109 * function also assumes that the RTP packet contains all protocol relevant fields
110 * (SSRC, sequence number etc.) in network order.
111 *
112 * When encrypting the buffer must big enough to store additional data, usually
113 * 10 bytes if the application set the full authentication length (80 bit).
114 *
115 * @param buffer contains data in RTP packet format
116 *
117 * @param length length of the RTP packet data in buffer.
118 *
119 * @param newLength returns the new length of the RTP data. When encrypting
120 * @c newLength covers the additional SRTP authentication data.
121 *
122 * @return
123 * - @c true application shall send packet to the recipient.
124 * - @c false don't send the packet.
125 */
126 bool processOutgoingRtp(uint8_t *buffer, size_t length, size_t *newLength);
127
128 /**
129 * @brief Process incoming data.
130 *
131 * Depending on the state of the buffer the functions either returns the RTP data
132 * in the buffer either umodified or decrypted. An additional status is @c drop.
133 * The functions returns this status if the application must not process this
134 * RTP data. The function handled these packets as ZRTP packets.
135 *
136 * The function takes a uint8_t buffer that must contain RTP or ZRTP packet data.
137 * The function also assumes that the RTP/ZRTP packet contains all protocol relevant
138 * fields (SSRC, sequence number etc.) in network order or in the order defined
139 * for the protocol.
140 *
141 * @param buffer contains data in RTP/ZRTP packet format
142 *
143 * @param length length of the RTP/ZRTP packet data in buffer.
144 *
145 * @param newLength returns the new length of the RTP data. When encrypting
146 * @c newLength covers the additional SRTP authentication data.
147 *
148 * @return 1: success, 0: not an error but drop packet, -1: SRTP authentication failed,
149 * -2: SRTP replay check failed
150 */
151 int32_t processIncomingRtp(uint8_t* buffer, const size_t length, size_t* newLength);
152
153 /**
154 * @brief Get the ZRTP Hello hash to be used for signaling
155 *
156 * Refer to RFC 6189 chapter 8 to get the full documentation on the intercation
157 * between ZRTP and a signaling layer.
158 *
159 * @param helloHash points to a character buffer with a length of at least 65 characters.
160 * The method fills it with the hex string part of the ZRTP hello hash and
161 * terminates it with a @c nul byte.
162 *
163 * @param index Hello hash of the Hello packet identfied by index. Index must
164 * be 0 <= index < getNumberSupportedVersions().
165 *
166 * @return the number of characters in the @c helloHash buffer.
167 */
168 int getSignalingHelloHash(char *helloHash, int32_t index);
169
170 /**
171 * @brief Set the ZRTP Hello hash from signaling
172 *
173 * Refer to RFC 6189 chapter 8 to get the full documentation on the intercation
174 * between ZRTP and a signaling layer.
175 *
176 * @param helloHash is the ZRTP hello hash string from the signaling layer
177 */
178 void setSignalingHelloHash(const char *helloHash);
179
180 /**
181 * @brief Checks the security state of the stream.
182 *
183 * @return non null if either @c eSecure, @c eSecureMitm , @c eSecureMitmVia
184 * or @c eSecureSdes is set.
185 */
186 int isSecure();
187
188 /**
189 * Return information to tivi client.
190 *
191 * @param key which information to return
192 *
193 * @param buffer points to buffer that gets the information
194 *
195 * @param maxLen length of the buffer
196 */
197 int getInfo(const char *key, char *buffer, int maxLen);
198
199 bool isStarted() {return started;}
200
201 bool isEnabled() {return enableZrtp;}
202
203 /**
204 * Accept enrollment for the active peer.
205 *
206 * The method checks if a name is already set in the name cache. If no name
207 * is found then set the name for this peer in the name cache.
208 *
209 * @param p this is the human readable name for this peer.
210 */
211 int enrollAccepted(char *p);
212
213 /**
214 * Denies enrollment for the active peer.
215 *
216 * The methods resets the stored PBX secret to @c invalid and resets the peer's
217 * name in the name cahce to an empty string.
218 */
219 int enrollDenied();
220
221 /**
222 * @brief Creates an SDES crypto string for the SDES/ZRTP stream.
223 *
224 * Creates and returns a SDES crypto string for the client that sends
225 * the SIP INVITE.
226 *
227 * @param cryptoString points to a char output buffer that receives the
228 * crypto string in the raw format, without the any
229 * signaling prefix, for example @c a=crypto: in case
230 * of SDP signaling. The function terminates the
231 * crypto string with a @c nul byte
232 *
233 * @param maxLen length of the crypto string buffer. On return it contains the
234 * actual length of the crypto string.
235 *
236 * @param suite defines which crypto suite to use for this stream. The values are
237 * @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32.
238 *
239 * @return @c true if data could be created, @c false otherwise.
240 */
241 bool createSdes(char *cryptoString, size_t *maxLen, const ZrtpSdesStream::sdesSuites suite =ZrtpSdesStream::AES_CM_128_HMAC_SHA1_32);
242
243 /**
244 * @brief Parses an SDES crypto string for the SDES/ZRTP stream.
245 *
246 * Parses a received crypto string that the application received in a SIP INVITE
247 * or SIP 200 OK.
248 *
249 * An INVITE-ing application shall call this function right after it received
250 * the 200 OK from the answering application and must call this function with the
251 * @c sipInvite parameter set to @c true. This usually at the same point when
252 * it gets the @c zrtp-hash from the SDP parameters. This application's SRTP
253 * environment is now ready. The method ignores the @c sendCryptoStr parameter
254 * and its length if @c sipInvite is true.
255 *
256 * The answering application calls this function after it received the INVITE and
257 * extracted the crypto string from the SDP and must call this function with the
258 * @c sipInvite parameter set to @c false. This is usually the same point when
259 * it gets the @c zrtp-hash from the SDP parameters. The answering client must
260 * provide a @c sendCryptoStr buffer. The method fills this buffer with the crypto
261 * string that the answering client sends with 200 OK.
262 *
263 * @param recvCryptoStr points to the received crypto string in raw format,
264 * without any signaling prefix, for example @c
265 * a=crypto: in case of SDP signaling.
266 *
267 * @param recvLenght length of the received crypto string. If the length is
268 * @c zero then the method uses @c strlen to compute
269 * the length.
270 *
271 * @param sendCryptoStr points to a buffer. The method stores a crypto string
272 * in raw format in this buffer (without any signaling prefix, for
273 * example @c a=crypto: in case of SDP signaling. If the answering client
274 * does not provide a buffer (sendCryptoStr == NULL) then the method
275 * stores the string in a temporary buffer and the client can get the
276 * string at a later time using getSavedSdes().
277 *
278 * @param sendLenght length of the send crypto string buffer. On return it contains the
279 * actual length of the crypto string.
280 *
281 * @param sipInvite the client that sent the SIP INVITE must set this to @c true.
282 *
283 * @return @c true if data could be created, @c false otherwise.
284 */
285 bool parseSdes(char *recvCryptoStr, size_t recvLength, char *sendCryptoStr, size_t *sendLength, bool sipInvite);
286
287 /**
288 * @brief Get the saved SDES crypto string.
289 *
290 * Refer to parseSdes() documentation.
291 *
292 * @param sendCryptoStr points to a buffer. The method stores the saved crypto string
293 * in this buffer.
294 *
295 * @param sendLenght length of the send crypto string buffer. On return it contains the
296 * actual length of the crypto string.
297 *
298 * @return @c true if data could be copied, @c false otherwise, i.e buffer length too short.
299 */
300 bool getSavedSdes(char *sendCryptoStr, size_t *sendLength);
301
302 /**
303 * @brief Check if SDES is active and is in SDES secure state.
304 *
305 * @return @c true if SDES is in secure state, @c false otherwise.
306 */
307 bool isSdesActive();
308
309 /**
310 * @brief Get Crypto Mix attribute string
311 *
312 * The offerer shall call this method to get a string of @b all supported crypto mix algorithms
313 * and shall send this list to the answerer.
314 *
315 * The answerer shall call this function only @b after it received the crypto mix string and
316 * called @c setCryptoMixAttribute(...). In this case the method returns only one (the selected)
317 * crypto mix algorithm and the answerer must send this to the offerer in 200 OK for example.
318 *
319 * @param algoNames points to a buffer that will filled with the crypto mix algorithm names.
320 * The buffer must be long enough to hold at least the name of the mandatory
321 * algorithm HMAC-SHA-384.
322 *
323 * @param length length buffer
324 *
325 * @return Length of algorithm names (excluding zero byte) or zero if crypto mix not supported or
326 * enabled.
327 */
328 int getCryptoMixAttribute(char *algoNames, size_t length);
329
330 /**
331 * @brief Set Crypto Mix attribute string
332 *
333 * The method splits the string into algorithm names and checks if it contains an
334 * supported algorithm.
335 *
336 * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method.
337 *
338 * The offerer call this method only @b after it received the selected algorithm in the answer.
339 *
340 * @param algoNames points to a buffer that holds the received crypto mix algorithm names.
341 * The buffer must be zero terminated.
342 *
343 * @return @c false if algorithm is not supported.
344 */
345 bool setCryptoMixAttribute(const char *algoNames);
346
347 /**
348 * @brief Reset SDES
349 *
350 * This method deletes an existing SDES context unconditionally. The application must make
351 * sure that it does not use the SDES context in any way, for example feeding RTP or SRTP packets
352 * to this stream.
353 *
354 * @param force if set to true then it resets the context unconditionally, otherwise only if
355 * SDES is not in active state.
356 */
357 void resetSdesContext(bool force =false);
358
359 /**
360 * @brief Get number of supported ZRTP protocol versions.
361 *
362 * @return the number of supported ZRTP protocol versions.
363 */
364 int32_t getNumberSupportedVersions();
365
366 /**
367 * @brief Get the supported ZRTP encapsulation attribute.
368 *
369 * Get this attribute value and set it as a SDP parameter to signal support of ZRTP encapsulation.
370 *
371 * @return the pointer to the attribute cC-string or @c NULL if encapsulation is not supported.
372 */
373 const char* getZrtpEncapAttribute();
374
375 /**
376 * @brief Set the ZRTP encapsulation attribute.
377 *
378 * If an application receives the ZRTP encapsulation SDP attribute then it should set the
379 * attribute value. The stream uses ZRTP encapsulation only if this SDP parameter is set
380 * @b and SDES is available and active.
381 *
382 * @param attribute pointer to a C-string that defines the ZRTP encapsulation method.
383 *
384 * @see getZrtpEncapAttribute
385 */
386 void setZrtpEncapAttribute(const char *attribute);
387
388 /**
389 * @brief Set the auxilliary secret for ZRTP
390 *
391 * An application may set an auxilliary secret and the ZRTP stack uses it as
392 * additional data to compute the SRTP keys.
393 *
394 * Only the master stream (Audio) can use the auxilliary secret because only the
395 * master stream performs a Diffie-Hellman negotiation.
396 *
397 * @param secret the secret data
398 * @param length the length of the secret data in bytes
399 */
400 void setAuxSecret(const unsigned char *secret, int length);
401
402 /*
403 * The following methods implement the GNU ZRTP callback interface.
404 * For detailed documentation refer to file ZrtpCallback.h
405 */
406 int32_t sendDataZRTP(const unsigned char* data, int32_t length);
407
408 int32_t activateTimer(int32_t time);
409
410 int32_t cancelTimer();
411
412 void sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
413
414 bool srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part);
415
416 void srtpSecretsOff(EnableSecurity part);
417
418 void srtpSecretsOn(std::string c, std::string s, bool verified);
419
420 void handleGoClear();
421
422 void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int32_t subCode);
423
424 void zrtpNotSuppOther();
425
426 void synchEnter();
427
428 void synchLeave();
429
430 void zrtpAskEnrollment(GnuZrtpCodes::InfoEnrollment info);
431
432 void zrtpInformEnrollment(GnuZrtpCodes::InfoEnrollment info);
433
434 void signSAS(uint8_t* sasHash);
435
436 bool checkSASSignature(uint8_t* sasHash);
437
438 /*
439 * End of ZrtpCallback functions.
440 */
441private:
442 CtZrtpSession::tiviStatus tiviState; //!< Status reported to Tivi client
443 CtZrtpSession::tiviStatus prevTiviState; //!< previous status reported to Tivi client
444
445 CryptoContext *recvSrtp; //!< The SRTP context for this stream
446 CryptoContextCtrl *recvSrtcp; //!< The SRTCP context for this stream
447 CryptoContext *sendSrtp; //!< The SRTP context for this stream
448 CryptoContextCtrl *sendSrtcp; //!< The SRTCP context for this stream
449 CtZrtpCb *zrtpUserCallback;
450 CtZrtpSendCb *zrtpSendCallback;
451
452 uint8_t zrtpBuffer[maxZrtpSize];
453 char sdesTempBuffer[maxSdesString];
454 uint16_t senderZrtpSeqNo;
455 uint32_t peerSSRC;
456 std::vector<std::string> peerHelloHashes;
457 bool zrtpHashMatch;
458 bool sasVerified;
459 bool helloReceived;
460 bool useSdesForMedia;
461 bool useZrtpTunnel;
462 bool zrtpEncapSignaled;
463 ZrtpSdesStream *sdes;
464
465 uint32_t supressCounter;
466 uint32_t srtpAuthErrorBurst;
467 uint32_t srtpReplayErrorBurst;
468 uint32_t srtpDecodeErrorBurst;
469 uint32_t zrtpCrcErrors;
470
471 CMutexClass *synchLock;
472
473 char mixAlgoName[20]; //!< stores name in during getInfo() call
474
475 int role; //!< Initiator or Responder role
476
477 void initStrings();
478};
479
480#endif /* _CTZRTPSTREAM_H_ */