blob: 89288e7b78d18e776a450932eaa98d373dc0ba20 [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#ifndef _CTZRTPSESSION_H_
9#define _CTZRTPSESSION_H_
10
11#include <stdio.h>
12#include <stdint.h>
13#include <string>
14#include <string.h>
15
16#ifndef __EXPORT
17 #if (defined _WIN32 || defined __CYGWIN__) && defined(_DLL)
18 #define __EXPORT __declspec(dllimport)
19 #define __LOCAL
20 #elif __GNUC__ >= 4
21 #define __EXPORT __attribute__ ((visibility("default")))
22 #define __LOCAL __attribute__ ((visibility("hidden")))
23 #else
24 #define __EXPORT
25 #define __LOCAL
26 #endif
27#endif
28
29
30class CtZrtpStream;
31class CtZrtpCb;
32class CtZrtpSendCb;
33class ZrtpConfigure;
34class CMutexClass;
35
36extern "C" __EXPORT const char *getZrtpBuildInfo();
37
38class __EXPORT CtZrtpSession {
39
40public:
41 typedef enum _streamName {
42 AudioStream = 0,
43 VideoStream = 1,
44 AllStreams = 2 //!< AllStreams is max number of streams
45 } streamName;
46
47 typedef enum _streamType {
48 NoStream = 0,
49 Master,
50 Slave
51 } streamType;
52
53 typedef enum _tiviStatus {
54 eLookingPeer,
55 eNoPeer,
56 eGoingSecure,
57 eError,
58 eSecure,
59 eSecureMitm,
60 eSecureMitmVia,
61 eSecureSdes,
62 eSecurityDisabled,
63 eWrongStream = -1
64 } tiviStatus;
65
66 /**
67 * Supported SDES crypto suites. Included here again to avoid #include of ZrtpSdesStream.h
68 * Keep in sync with same enum in ZrtpSdesStream.
69 */
70 typedef enum {
71 AES_CM_128_HMAC_SHA1_32 = 0,
72 AES_CM_128_HMAC_SHA1_80
73 } sdesSuites;
74
75
76 typedef enum _retCodes {
77 ok = 0, /** OK status */
78 fail = 1 /** General, unspecified failure */
79 } returnCodes;
80
81 CtZrtpSession();
82
83 ~CtZrtpSession();
84
85 /**
86 * @brief Intialize the cache file singleton.
87 *
88 * Opens and initializes the cache file instance.
89 *
90 * @param zidFilename
91 * The name of the ZID file, can be a relative or absolut
92 * filename.
93 *
94 * @return
95 * 1 on success, -1 on failure
96 */
97 static int initCache(const char *zidFilename);
98
99 /** @brief Initialize CtZrtpSession.
100 *
101 * Before an application can use ZRTP it has to initialize the
102 * ZRTP implementation. This method initializes the timeout
103 * thread and opens a file that contains ZRTP specific
104 * information such as the applications ZID (ZRTP id) and its
105 * retained shared secrets.
106 *
107 * If one application requires several ZRTP sessions all
108 * sessions use the same timeout thread and use the same ZID
109 * file. Therefore an application does not need to do any
110 * synchronisation regading ZID files or timeouts. This is
111 * managed by the ZRTP implementation.
112 *
113 * The application may specify its own ZID file name. If no
114 * ZID file name is specified it defaults to
115 * <code>$HOME/.GNUccRTP.zid</code> if the <code>HOME</code>
116 * environment variable is set. If it is not set the current
117 * directory is used.
118 *
119 * @param audio
120 * set to @c true if audio stream shout be initialized
121 *
122 * @param video
123 * set to @c true if video stream shoud be initialized.
124 *
125 * @param config
126 * this parameter points to ZRTP configuration data. If it is
127 * NULL then ZrtpQueue uses a default setting. Default is NULL.
128 *
129 * @return
130 * 1 on success, ZRTP processing enabled, -1 on failure,
131 * ZRTP processing disabled.
132 *
133 */
134 int init(bool audio, bool video, ZrtpConfigure* config = NULL);
135
136 /**
137 * @brief Fills a ZrtpConfiguration based on selected algorithms.
138 *
139 * The method looks up some global keys and enables or disables various
140 * algorithms. The method creates the configuration for the publik key
141 * algorithms in a way that follows RFC 6189, chapter 4.1.2
142 */
143 void setupConfiguration(ZrtpConfigure *conf);
144
145 /**
146 * @brief Set the application's callback class.
147 *
148 * @param ucb
149 * Implementation of the application's callback class
150 */
151 void setUserCallback(CtZrtpCb* ucb, streamName streamNm);
152
153 /**
154 * @brief Set the application's send data callback class.
155 *
156 *
157 * @param ucb
158 * Implementation of the application's send data callback class
159 */
160 void setSendCallback(CtZrtpSendCb* scb, streamName streamNm);
161
162 /**
163 * @brief Start a stream if it is not already started.
164 *
165 * The method starts a stream if it is not already started and it starts
166 * a video stream (Slave) only if the audio stream (Master) is already secure.
167 */
168 int startIfNotStarted(unsigned int uiSSRC, int streamNm);
169
170 /**
171 * @brief Start a stream.
172 *
173 * If this start command specifies the @c Master stream the method starts it
174 * immediately. The ZRTP engine immediatley send the first Hello packet.
175 *
176 * The functions my delay the start of a @c Slave stream until the @c Master
177 * stream enters secure mode. The functions then gets the multi-stream data
178 * from the master stream and copies it into the @c Slave streams and starts
179 * them.
180 *
181 * If the @c Master stream is already in secure mode then the function copies
182 * the multi-stream parameters to the @c slave and starts it immediately.
183 *
184 * @param uiSSRC the local SSRC for the stream
185 *
186 * @param streamNm which stream to start.
187 */
188 void start(unsigned int uiSSRC, streamName streamNm);
189
190 /**
191 * @brief Stop a stream.
192 *
193 * Stop a stream and remove it from the session. To create a new stream
194 * see @c newStream
195 *
196 * @param streamNm which stream to stop.
197 */
198 void stop(streamName streamNm);
199
200 /**
201 * @brief Release all streams in this session.
202 *
203 * All streams are reset to their initiali values. The application may call
204 * @c init to initialize stream(s) again. A stream can be started only if it
205 * was initialized.
206 */
207 void release();
208
209 /**
210 * @brief Release all resources for the stream.
211 *
212 * @param streamNm which stream to release.
213 */
214 void release(streamName streamNm);
215
216 /**
217 * @brief Set peer name of current call's peer.
218 *
219 * Setting the peer name will always use the AudioStream to determine
220 * the ZID and set the name into the name cache.
221 */
222 void setLastPeerNameVerify(const char *name, int iIsMitm);
223
224 /**
225 * @brief Process outgoing data.
226 *
227 * Depending on the state of the buffer the functions either returns the buffer
228 * umodified or encrypted.
229 *
230 * The function takes a uint8_t buffer that must contain RTP packet data. The
231 * function also assumes that the RTP packet contains all protocol relevant fields
232 * (SSRC, sequence number etc.) in network order.
233 *
234 * When encrypting the buffer must big enough to store additional data, usually
235 * 10 bytes if the application set the full authentication length (80 bit).
236 *
237 * @param buffer contains data in RTP packet format
238 *
239 * @param length length of the RTP packet data in buffer.
240 *
241 * @param newLength returns the new length of the RTP data. When encrypting
242 * @c newLength covers the additional SRTP authentication data.
243 *
244 * @param streamNm specifies which stream to use
245 *
246 * @return
247 * - @c true application shall send packet to the recipient.
248 * - @c false don't send the packet.
249 */
250 bool processOutoingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm);
251
252 /**
253 * @brief Process incoming data.
254 *
255 * Depending on the state of the buffer the functions either returns the RTP data
256 * in the buffer either umodified or decrypted. An additional status is @c drop.
257 * The functions returns this status if the application must not process this
258 * RTP data. The function handled these packets as ZRTP packets.
259 *
260 * The function takes a uint8_t buffer that must contain RTP or ZRTP packet data.
261 * The function also assumes that the RTP/ZRTP packet contains all protocol relevant
262 * fields (SSRC, sequence number etc.) in network order or in the order defined
263 * for the protocol.
264 *
265 * @param buffer contains data in RTP/ZRTP packet format
266 *
267 * @param length length of the RTP/ZRTP packet data in buffer.
268 *
269 * @param newLength returns the new length of the RTP data. When encrypting
270 * @c newLength covers the additional SRTP authentication data.
271 *
272 * @param streamNm specifies which stream to use
273 *
274 * @return
275 * - 1: success,
276 * - 0: drop packet, not an error
277 * - -1: SRTP authentication failed,
278 * - -2: SRTP replay check failed
279 */
280 int32_t processIncomingRtp(uint8_t *buffer, size_t length, size_t *newLength, streamName streamNm);
281
282 /**
283 * @brief Check if a stream was started.
284 *
285 * @return @c true is started, @c false otherwise.
286 */
287 bool isStarted(streamName streamNm);
288
289 /**
290 * @brief Check if a stream is enabled for ZRTP.
291 *
292 * For slave streams this flag is @c true if the application called @c start() for
293 * this stream but the master stream is not yet in secure state.
294 *
295 * @return @c true is enabled, @c false otherwise.
296 */
297 bool isEnabled(streamName streamNm);
298
299 tiviStatus getCurrentState(streamName streamNm);
300
301 tiviStatus getPreviousState(streamName streamNm);
302
303 /**
304 * @brief Is ZRTP enabled for this session.
305 *
306 * @return @c true if ZRTP is enabled, @c false otherwise
307 */
308 bool isZrtpEnabled();
309
310 /**
311 * @brief Is SDES enabled for this session.
312 *
313 * @return @c true if SDES is enabled, @c false otherwise
314 */
315 bool isSdesEnabled();
316
317 /**
318 * @brief Enable or disable ZRTP processing for this session.
319 *
320 * If the application enabled ZRTP processing it should also call @c start
321 * to really start the ZRTP engines. An application can enable and start ZRTP
322 * processing any time during a RTP session.
323 *
324 * @param yesNo if @c true ZRTP processing is enabled.
325 */
326 void setZrtpEnabled(bool yesNo);
327
328 /**
329 * @brief Enable or disable SDES processing for this session.
330 *
331 * If SDES processing is not enabled the functions @c createSdes and @c parseSdes
332 * always return false.
333 *
334 * Enabling SDES processing after SIP signaling ended does not make sense.
335 *
336 * @param yesNo if @c true SDES processing is enabled.
337 */
338 void setSdesEnabled(bool yesNo);
339
340 /**
341 * @brief Get the ZRTP Hello hash to be used for signaling.
342 *
343 * Refer to RFC 6189 chapter 8 to get the full documentation on the intercation
344 * between ZRTP and a signaling layer.
345 *
346 * @param helloHash points to a character buffer with a length of at least 65 characters.
347 * The method fills it with the hex string part of the ZRTP hello hash and
348 * terminates it with a @c nul byte.
349 *
350 * @param streamNm specifies which stream for this hello hash.
351 *
352 * @param index Hello hash of the Hello packet identfied by index. Index must
353 * be 0 <= index < getNumberSupportedVersions().
354 *
355 * @return the number of characters in the @c helloHash buffer.
356 */
357 int getSignalingHelloHash(char *helloHash, streamName streamNm, int32_t index);
358
359 /**
360 * @brief Set the ZRTP Hello hash from signaling.
361 *
362 * Refer to RFC 6189 chapter 8 to get the full documentation on the intercation
363 * between ZRTP and a signaling layer.
364 *
365 * @param helloHash is the ZRTP hello hash string from the signaling layer
366 *
367 * @param streamNm specifies the stream
368 */
369 void setSignalingHelloHash(const char *helloHash, streamName streamNm);
370
371 /**
372 * @brief Set verification flag.
373 *
374 * If the user verified the SAS he/she should press a @c verify button and
375 * this button calls this method to set the verified flag in the cache. This
376 * always uses the @c Master stream (AudioStream).
377 *
378 * @param iVerified if not zero it sets the verified flag, otherwise the flag
379 * is reset.
380 */
381 void setVerify(int iVerified);
382
383 /**
384 * @brief Checks the security state of the stream.
385 *
386 *
387 * @param streamNm specifies which stream to check
388 *
389 * @return non null if either @c eSecure, @c eSecureMitm , @c eSecureMitmVia
390 * or @c eSecureSdes is set.
391 */
392 int isSecure(streamName streamNm);
393
394 /**
395 * @brief Return information to tivi client.
396 *
397 * @param key which information to return
398 *
399 * @param buffer points to buffer that gets the information
400 *
401 * @param length length of the buffer
402 *
403 * @param streamNm stream, if not specified the default is @c AudioStream
404 */
405 int getInfo(const char *key, uint8_t *buffer, size_t length, streamName streamNm =AudioStream);
406
407 /**
408 * @brief Accept enrollment for the active peer.
409 *
410 * The method checks if a name is already set in the name cache. If no name
411 * is found then set the name for this peer in the name cache.
412 *
413 * The Stream is always the master stream.
414 *
415 * @param p this is the human readable name for this peer.
416 */
417 int enrollAccepted(char *p);
418
419 /**
420 * @brief Denies enrollment for the active peer.
421 *
422 * The methods resets the stored PBX secret to @c invalid and resets the peer's
423 * name in the name cache to an empty string.
424 */
425 int enrollDenied();
426
427 /**
428 * @brief Set the client ID for ZRTP Hello message.
429 *
430 * The client may set its id to identify itself in the
431 * ZRTP Hello message. The maximum length is 16 characters. A
432 * shorter id string is possible, it will be filled with blanks. A
433 * longer id string will be truncated to 16 characters.
434 *
435 * Setting the client's id must be done before calling
436 * CtZrtpSession#init().
437 *
438 * @param id
439 * The client's id string
440 */
441 void setClientId(std::string id);
442
443 /**
444 * @brief Creates an SDES crypto string for the SDES/ZRTP stream.
445 *
446 * Creates and returns a SDES crypto string for the client that sends
447 * the SIP INVITE.
448 *
449 * @param cryptoString points to a char output buffer that receives the
450 * crypto string in the raw format, without the any
451 * signaling prefix, for example @c a=crypto: in case
452 * of SDP signaling. The function terminates the
453 * crypto string with a @c nul byte
454 *
455 * @param maxLen length of the crypto string buffer. On return it contains the
456 * actual length of the crypto string.
457 *
458 * @param streamNm stream identifier.
459 *
460 * @param suite defines which crypto suite to use for this stream. The values are
461 * @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32. Default
462 * if @c AES_CM_128_HMAC_SHA1_32.
463 *
464 * @return @c true if data could be created, @c false otherwise.
465 */
466 bool createSdes(char *cryptoString, size_t *maxLen, streamName streamNm, const sdesSuites suite =AES_CM_128_HMAC_SHA1_32);
467
468 /**
469 * @brief Parses an SDES crypto string for the SDES/ZRTP stream.
470 *
471 * Parses a received crypto string that the application received in a SIP INVITE
472 * or SIP 200 OK.
473 *
474 * An INVITE-ing application shall call this function right after it received
475 * the 200 OK from the answering application and must call this function with the
476 * @c sipInvite parameter set to @c true. This usually at the same point when
477 * it gets the @c zrtp-hash from the SDP parameters. This application's SRTP
478 * environment is now ready. The method ignores the @c sendCryptoStr parameter
479 * and its length if @c sipInvite is true.
480 *
481 * The answering application calls this function after it received the INVITE and
482 * extracted the crypto string from the SDP and must call this function with the
483 * @c sipInvite parameter set to @c false. This is usually the same point when
484 * it gets the @c zrtp-hash from the SDP parameters. The answering client must
485 * provide a @c sendCryptoStr buffer. The method fills this buffer with the crypto
486 * string that the answering client sends with 200 OK.
487 *
488 * @param recvCryptoStr points to the received crypto string in raw format,
489 * without any signaling prefix, for example @c
490 * a=crypto: in case of SDP signaling.
491 *
492 * @param recvLenght length of the received crypto string. If the length is
493 * @c zero then the method uses @c strlen to compute
494 * the length.
495 *
496 * @param sendCryptoStr points to a buffer. The method stores a crypto string
497 * in raw format in this buffer (without any signaling prefix, for
498 * example @c a=crypto: in case of SDP signaling. If the answering client
499 * does not provide a buffer (sendCryptoStr == NULL) then the method
500 * stores the string in a temporary buffer and the client can get the
501 * string at a later time using getSavedSdes().
502 *
503 * @param sendLenght length of the send crypto string buffer. On return it contains the
504 * actual length of the crypto string.
505 *
506 * @param sipInvite the client that sent the SIP INVITE must set this to @c true.
507 *
508 * @param streamNm stream identifier.
509 *
510 * @return @c true if data could be created, @c false otherwise.
511 */
512 bool parseSdes(char *recvCryptoStr, size_t recvLength, char *sendCryptoStr, size_t *sendLength, bool sipInvite, streamName streamNm);
513
514 /**
515 * @brief Get the saved SDES crypto string.
516 *
517 * Refer to parseSdes() documentation.
518 *
519 * @param sendCryptoStr points to a buffer. The method stores the saved crypto string
520 * in this buffer.
521 *
522 * @param sendLenght length of the send crypto string buffer. On return it contains the
523 * actual length of the crypto string.
524 *
525 * @param streamNm stream identifier.
526 *
527 * @return @c true if data could be copied, @c false otherwise, i.e buffer length too short.
528 */
529 bool getSavedSdes(char *sendCryptoStr, size_t *sendLength, streamName streamNm);
530
531 /**
532 * @brief Check if SDES is active.
533 *
534 * @param streamNm stream identifier.
535 *
536 * @return @c true if SDES context is available, @c false otherwise.
537 */
538 bool isSdesActive(streamName streamNm);
539
540 /**
541 * @brief Get Crypto Mix attribute string
542 *
543 * The @b offerer shall call this method to get a string of @b all supported crypto mix algorithms
544 * and shall send this list to the answerer.
545 *
546 * The @b answerer must call this function after it received the crypto mix string and @b after it
547 * called @c setCryptoMixAttribute(...). In this case the method returns only one (the selected)
548 * crypto mix algorithm and the answerer must send this to the offerer in 200 OK for example. Must
549 * be called before @c parseSdes
550 *
551 * @param algoNames points to a buffer that will filled with the crypto mix algorithm names.
552 * The buffer must be long enough to hold at least the name of the mandatory
553 * algorithm HMAC-SHA-384.
554 *
555 * @param streamNm stream identifier.
556 *
557 * @param length length buffer
558 *
559 * @return Length of algorithm names (excluding zero byte) or zero if crypto mix not supported or
560 * enabled.
561 */
562 int getCryptoMixAttribute(char *algoNames, size_t length, streamName streamNm);
563
564 /**
565 * @brief Set Crypto Mix attribute string
566 *
567 * The method splits the string into algorithm names and checks if it contains an
568 * supported algorithm.
569 *
570 * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method and
571 * @b before it calls the @c parseSdes method.
572 *
573 * The offerer call this method @b before it calls @c parseSdes
574 *
575 * @param algoNames points to a buffer that holds the received crypto mix algorithm names.
576 * The buffer must be zero terminated.
577 *
578 * @param streamNm stream identifier.
579 *
580 * @return @c false if algorithm is not supported.
581 */
582 bool setCryptoMixAttribute(const char *algoNames, streamName streamNm);
583
584 /**
585 * @brief Reset SDES
586 *
587 * This method deletes an existing SDES context unconditionally. The application must make
588 * sure that it does not use the SDES context in any way, for example feeding RTP or SRTP packets
589 * to this stream.
590 *
591 * @param streamNm stream identifier.
592 *
593 * @param force if set to true then it resets the context unconditionally, otherwise only if
594 * SDES is not in active state.
595 */
596 void resetSdesContext(streamName streamNm, bool force =false);
597
598 /**
599 * @brief Clean Cache
600 *
601 * This method does not work for file based cache implementation. An application
602 * shall use this functions with great care because it drops all stored retained
603 * secrets.
604 *
605 * The cache must be initialized and open.
606 */
607 static void cleanCache();
608
609 /**
610 * @brief Get number of supported ZRTP protocol versions.
611 *
612 * @param streamNm stream identifier.
613 *
614 * @return the number of supported ZRTP protocol versions.
615 */
616 int32_t getNumberSupportedVersions(streamName streamNm);
617
618 /**
619 * @brief Get the supported ZRTP encapsulation attribute.
620 *
621 * Get this attribute value and set it as a SDP parameter to signal support of ZRTP encapsulation.
622 *
623 * @param streamNm stream identifier.
624 *
625 * @return the pointer to the attribute cC-string or @c NULL if encapsulation is not supported.
626 */
627 const char* getZrtpEncapAttribute(streamName streamNm);
628
629 /**
630 * @brief Set the ZRTP encapsulation attribute.
631 *
632 * If an application receives the ZRTP encapsulation SDP attribute then it should set the
633 * attribute value. The stream uses ZRTP encapsulation only if this SDP parameter is set
634 * @b and SDES is available and active.
635 *
636 * @param attribute pointer to a C-string that defines the ZRTP encapsulation method.
637 * @param streamNm stream identifier.
638 *
639 * @see getZrtpEncapAttribute
640 */
641 void setZrtpEncapAttribute(const char *attribute, streamName streamNm);
642
643 /**
644 * @brief Set the auxilliary secret for ZRTP
645 *
646 * An application may set an auxilliary secret and the ZRTP stack uses it as
647 * additional data to compute the SRTP keys.
648 *
649 * Only the master stream (Audio) can use the auxilliary secret because only the
650 * master stream performs a Diffie-Hellman negotiation.
651 *
652 * @param secret the secret data
653 * @param length the length of the secret data in bytes
654 */
655 void setAuxSecret(const unsigned char *secret, int length);
656
657protected:
658 friend class CtZrtpStream;
659
660 /**
661 * @brief Session master stream entered secure state.
662 *
663 * The session's master stream entered secure state and computed all
664 * necessary information to kick of slave streams. The session checks
665 * if slave streams are available and if they are ready to start.
666 *
667 * @param stream is the stream that enters secure mode. This must be a
668 * @c Master stream
669 */
670 void masterStreamSecure(CtZrtpStream *stream);
671
672
673private:
674 void synchEnter();
675 void synchLeave();
676
677 CtZrtpStream *streams[AllStreams];
678 std::string clientIdString;
679 std::string multiStreamParameter;
680 const uint8_t* ownZid;
681
682 bool mitmMode;
683 bool signSas;
684 bool enableParanoidMode;
685 bool isReady;
686 bool zrtpEnabled;
687 bool sdesEnabled;
688};
689
690#endif /* _CTZRTPSESSION_H_ */