source: verona/oRTP/src/zrtp.c @ 519:bc6c6ba9142e

Last change on this file since 519:bc6c6ba9142e was 519:bc6c6ba9142e, checked in by laurent <laurent@…>, 7 months ago

update oRTP

File size: 29.2 KB
Line 
1/*
2  The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
3  Copyright (C) 2011 Belledonne Communications
4
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18*/
19
20#if defined(_MSC_VER)  && (defined(WIN32) || defined(_WIN32_WCE))
21#include "ortp-config-win32.h"
22#elif HAVE_CONFIG_H
23#include "ortp-config.h"
24#endif
25
26#include "ortp/ortp.h"
27#include "rtpsession_priv.h"
28
29#include "ortp/zrtp.h"
30
31#ifdef WIN32
32#include <malloc.h>
33#endif
34
35#ifdef HAVE_zrtp
36
37
38// Minimum packet length is 3 + 3 (HelloAck) + 1 = 7 uint_32t
39#define ZRTP_MIN_MSG_LENGTH 28
40
41// ZRTP message is prefixed by RTP header
42#define ZRTP_MESSAGE_OFFSET 12
43
44#define SRTP_PAD_BYTES (SRTP_MAX_TRAILER_LEN + 4)
45//                                  1234567890123456
46static const char userAgentStr[] = "LINPHONE-ZRTPCPP"; // 16 chars max.
47
48struct _OrtpZrtpContext{
49        ortp_mutex_t mutex;
50        RtpSession *session;
51        uint32_t timerWillTriggerAt;
52        uint16_t last_recv_zrtp_seq_number;
53        uint16_t last_sent_zrtp_seq_number;
54        srtp_t srtpSend;
55        srtp_t srtpRecv;
56        zrtp_Callbacks zrtp_cb;
57        ZrtpContext *zrtpContext; // back link
58        RtpTransport rtpt;
59        RtpTransport rtcpt;
60};
61
62typedef enum {
63        rtp_stream,
64        rtcp_stream
65} stream_type;
66
67
68
69// Helper functions
70static inline OrtpZrtpContext* user_data(ZrtpContext *c) {
71        return (OrtpZrtpContext*) c->userData;
72}
73
74static inline uint64_t convert_timeval_to_millis(struct timeval *t) {
75        uint32_t ret=(1000LL*t->tv_sec)+(t->tv_usec/1000LL);
76        return ret;
77}
78
79static void check_timer(ZrtpContext *zrtpContext, OrtpZrtpContext *c) {
80        if (c->timerWillTriggerAt != 0) {
81                struct timeval t;
82                gettimeofday(&t,NULL);
83                uint64_t now=convert_timeval_to_millis(&t);
84                if (now > c->timerWillTriggerAt) {
85                        c->timerWillTriggerAt=0;
86                        zrtp_processTimeout(zrtpContext);
87                }
88        }
89}
90
91static void parseZrtpMessageType(char *messageType, const uint8_t* data) {
92        memcpy(messageType, data+4,8);
93        messageType[8]=0;
94}
95
96/* Structure of ZRTP packet (taken from the RFC)
97    0                   1                   2                   3
98    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
99   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100   |0 0 0 1|Not Used (set to zero) |         Sequence Number       |
101   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102   |                 Magic Cookie 'ZRTP' (0x5a525450)              |
103   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104   |                        Source Identifier                      |
105   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106   |                                                               |
107   |           ZRTP Message (length depends on Message Type)       |
108   |                            . . .                              |
109   |                                                               |
110   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111   |                          CRC (1 word)                         |
112   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113                       Figure 2: ZRTP Packet Format
114*/
115
116/* Structure of ZRTP Message (taken from RFC)
117    0                   1                   2                   3
118    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
119   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120   |0 1 0 1 0 0 0 0 0 1 0 1 1 0 1 0|             length            |
121   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122   |            Message Type Block="the type" (2 words)            |
123   |                                                               |
124   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 */
126static inline uint16_t get_rtp_seqnumber(const uint8_t *rtp) {
127        return ntohs(*(uint16_t*)(rtp+2));
128}
129
130static inline uint16_t get_zrtp_message_length(const uint8_t *zrtp_message){
131        return ntohs(*(uint16_t*)(zrtp_message+2));
132}
133
134static inline uint32_t get_zrtp_packet_crc(const uint32_t *zrtp_packet, uint16_t zrtp_message_length) {
135        return ntohl(*(zrtp_packet + ZRTP_MESSAGE_OFFSET/4 + zrtp_message_length));
136}
137
138static const char *zrtpErrorType="Error   ";
139static void print_zrtp_packet(const char *info, const uint8_t *rtp) {
140        const uint8_t *zmessage=rtp+ZRTP_MESSAGE_OFFSET;
141        uint16_t zmessage_seq=get_rtp_seqnumber(rtp);
142
143        char msgType[9];
144        parseZrtpMessageType(msgType, zmessage);
145
146/*      uint16_t zmessage_length = get_zrtp_message_length(zmessage);
147        uint32_t crc = get_zrtp_packet_crc((uint32_t*) rtp, zmessage_length);
148
149        ortp_message("%s ZRTP seq=%u type=%s CRC=%u, ln=%u",
150                        info, zmessage_seq, msgType, crc, zmessage_length);
151*/
152
153    if (strcmp(zrtpErrorType, msgType) == 0) {
154        uint32_t *msg32=(uint32_t*)zmessage;
155        uint32_t errcode=ntohl(msg32[3]);
156        ortp_error("%s ZRTP %s 0x%x %u", info, msgType, errcode, zmessage_seq);
157    } else {
158        ortp_message("%s ZRTP %s %u", info, msgType, zmessage_seq);
159    }
160
161/*      uint32_t *msg32=(uint32_t*)zmessage;
162        int i=0;
163        for (; i<zmessage_length; i++) {
164                ortp_message("%u", ntohl(msg32[i]));
165        }*/
166}
167
168
169
170/* ZRTP library Callbacks implementation */
171
172/**
173* Send a ZRTP packet via RTP.
174*
175* ZRTP calls this method to send a ZRTP packet via the RTP session.
176*
177* @param ctx
178*    Pointer to the opaque ZrtpContext structure.
179* @param data
180*    Points to ZRTP message to send.
181* @param length
182*    The length in bytes of the data
183* @return
184*    zero if sending failed, one if packet was sent
185*/
186static int32_t ozrtp_sendDataZRTP (ZrtpContext* ctx, const uint8_t* data, const int32_t length ){
187        OrtpZrtpContext *userData = user_data(ctx);
188        RtpSession *session = userData->session;
189        struct sockaddr *destaddr=(struct sockaddr*)&session->rtp.rem_addr;
190        socklen_t destlen=session->rtp.rem_addrlen;
191        ortp_socket_t sockfd=session->rtp.socket;
192
193        // Create ZRTP packet
194
195        int32_t newlength = length + 3*4; // strangely, given length includes CRC size !!!!
196        uint32_t* buffer32 = alloca(newlength);
197        uint8_t *buffer8=(uint8_t*)buffer32;
198        uint16_t *buffer16=(uint16_t*)buffer32;
199
200        uint16_t seqNumber=userData->last_sent_zrtp_seq_number++;
201
202        *buffer8 = 0x10;
203        buffer8[1]=0;
204        buffer16[1] = htons(seqNumber);
205        buffer32[1] = htonl(ZRTP_MAGIC);
206        buffer32[2] = htonl(session->snd.ssrc);
207        memcpy(buffer32+3, data, length);
208        uint32_t cks=zrtp_EndCksum(zrtp_GenerateCksum(buffer8, newlength-CRC_SIZE));
209        buffer32[newlength/4-1] = htonl(cks);
210
211        print_zrtp_packet("sent", buffer8);
212
213        // Send packet
214        ssize_t bytesSent = sendto(sockfd, (void*)buffer8, newlength,0,destaddr,destlen);
215        if (bytesSent == -1 || bytesSent < length) {
216                ortp_error("zrtp_sendDataZRTP: sent only %d bytes out of %d", (int)bytesSent, length);
217                return 0;
218        } else {
219                return 1;
220        }
221}
222
223
224/**
225* Activate timer.
226*
227* @param ctx
228*    Pointer to the opaque ZrtpContext structure.
229* @param time
230*    The time in ms for the timer
231* @return
232*    zero if activation failed, one if timer was activated
233*/
234static int32_t ozrtp_activateTimer (ZrtpContext* ctx, int32_t time ) {
235        if (user_data(ctx)->timerWillTriggerAt != 0) {
236                ortp_error("zrtp_activateTimer while another timer already active");
237                return 0;
238        }
239        struct timeval t;
240        gettimeofday(&t,NULL);
241        user_data(ctx)->timerWillTriggerAt=time+convert_timeval_to_millis(&t);
242        return 1;
243}
244
245/**
246* Cancel the active timer.
247*
248* @param ctx
249*    Pointer to the opaque ZrtpContext structure.
250* @return
251*    zero if cancel action failed, one if timer was canceled
252*/
253static int32_t ozrtp_cancelTimer(ZrtpContext* ctx) {
254        user_data(ctx)->timerWillTriggerAt=0;
255        return 1;
256}
257
258/**
259* Send information messages to the hosting environment.
260*
261* The ZRTP implementation uses this method to send information
262* messages to the host. Along with the message ZRTP provides a
263* severity indicator that defines: Info, Warning, Error,
264* Alert. Refer to the <code>MessageSeverity</code> enum above.
265*
266* @param ctx
267*    Pointer to the opaque ZrtpContext structure.
268* @param severity
269*     This defines the message's severity
270* @param subCode
271*     The subcode identifying the reason.
272* @see ZrtpCodes#MessageSeverity
273*/
274static void ozrtp_sendInfo (ZrtpContext* ctx, int32_t severity, int32_t subCode ) {
275        const char* submsg;
276        switch (subCode) {
277                case zrtp_InfoHelloReceived:
278                        /*!< Hello received, preparing a Commit */
279                        submsg="zrtp_InfoHelloReceived";
280                        break;
281                case zrtp_InfoCommitDHGenerated:
282                        /*!< Commit: Generated a public DH key */
283                        submsg="zrtp_InfoCommitDHGenerated";
284                        break;
285                case zrtp_InfoRespCommitReceived:
286                         /*!< Responder: Commit received, preparing DHPart1 */
287                        submsg="zrtp_InfoRespCommitReceived";
288                        break;
289                case zrtp_InfoDH1DHGenerated:
290                        /*!< DH1Part: Generated a public DH key */
291                        submsg="zrtp_InfoDH1DHGenerated";
292                        break;
293                case zrtp_InfoInitDH1Received:
294           /*!< Initiator: DHPart1 received, preparing DHPart2 */
295                        submsg="zrtp_InfoInitDH1Received";
296                        break;
297                case zrtp_InfoRespDH2Received:
298                        /*!< Responder: DHPart2 received, preparing Confirm1 */
299                        submsg="zrtp_InfoRespDH2Received";
300                        break;
301                case zrtp_InfoInitConf1Received:
302                        /*!< Initiator: Confirm1 received, preparing Confirm2 */
303                        submsg="zrtp_InfoInitConf1Received";
304                        break;
305                case zrtp_InfoRespConf2Received:
306                        /*!< Responder: Confirm2 received, preparing Conf2Ack */
307                        submsg="zrtp_InfoRespConf2Received";
308                        break;
309                case zrtp_InfoRSMatchFound:
310                        /*!< At least one retained secrets matches - security OK */
311                        submsg="zrtp_InfoRSMatchFound";
312                        break;
313                case zrtp_InfoSecureStateOn:
314                        /*!< Entered secure state */
315                        submsg="zrtp_InfoSecureStateOn";
316                        break;
317                case zrtp_InfoSecureStateOff:
318                        /*!< No more security for this session */
319                        submsg="zrtp_InfoSecureStateOff";
320                        break;
321                default:
322                        submsg="unkwown";
323                        break;
324        }
325
326        switch (severity) {
327                case zrtp_Info:
328                        ortp_message("ZRTP INFO %s",submsg);
329                        break;
330                case zrtp_Warning: /*!< A Warning message - security can be established */
331                        ortp_warning("ZRTP %s",submsg);
332                        break;
333                case zrtp_Severe:/*!< Severe error, security will not be established */
334                        ortp_error("ZRTP SEVERE %s",submsg);
335                        break;
336                case zrtp_ZrtpError:
337                        ortp_error("ZRTP ERROR %s",submsg);
338                        break;
339                default:
340                        ortp_error("ZRTP UNKNOWN ERROR %s",submsg);
341                        break;
342        }
343
344
345        if (subCode == zrtp_InfoSecureStateOn || subCode == zrtp_InfoSecureStateOff) {
346                OrtpEventData *eventData;
347                OrtpEvent *ev;
348                ev=ortp_event_new(ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED);
349                eventData=ortp_event_get_data(ev);
350                eventData->info.zrtp_stream_encrypted=(subCode == zrtp_InfoSecureStateOn);
351                rtp_session_dispatch_event(user_data(ctx)->session, ev);
352        }
353}
354
355
356/** returned key need to be fred.*/
357static uint8_t *key_with_salt(C_SrtpSecret_t* s, int32_t role) {
358        uint8_t *saltedKey;
359        const int pad=128;
360        if (role == Initiator) {
361                saltedKey=ortp_malloc0((s->initKeyLen + s->initSaltLen + pad)/8);
362                memcpy(saltedKey, s->keyInitiator, s->initKeyLen/8);
363                memcpy(saltedKey + s->initKeyLen/8, s->saltInitiator, s->initSaltLen/8);
364        } else {
365                saltedKey=ortp_malloc0((s->respKeyLen + s->respSaltLen + pad)/8);
366                memcpy(saltedKey, s->keyResponder, s->respKeyLen/8);
367                memcpy(saltedKey + s->respKeyLen/8, s->saltResponder, s->respSaltLen/8);
368        }
369        return saltedKey;
370}
371
372
373/**
374 * SRTP crypto data ready for the sender or receiver.
375 *
376 * The ZRTP implementation calls this method right after all SRTP
377 * secrets are computed and ready to be used. The parameter points
378 * to a structure that contains pointers to the SRTP secrets and a
379 * <code>enum Role</code>. The called method (the implementation
380 * of this abstract method) must either copy the pointers to the SRTP
381 * data or the SRTP data itself to a save place. The SrtpSecret_t
382 * structure is destroyed after the callback method returns to the
383 * ZRTP implementation.
384 *
385 * The SRTP data themselves are obtained in the ZRtp object and are
386 * valid as long as the ZRtp object is active. TheZRtp's
387 * destructor clears the secrets. Thus the called method needs to
388 * save the pointers only, ZRtp takes care of the data.
389 *
390 * The implementing class may enable SRTP processing in this
391 * method or delay it to srtpSecertsOn().
392 *
393 * @param ctx
394 *    Pointer to the opaque ZrtpContext structure.
395 * @param secrets A pointer to a SrtpSecret_t structure that
396 *     contains all necessary data.
397 *
398 * @param part for which part (Sender or Receiver) this data is
399 *     valid.
400 *
401 * @return Returns false if something went wrong during
402 *    initialization of SRTP context, for example memory shortage.
403 */
404static int32_t ozrtp_srtpSecretsReady (ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part ) {
405        srtp_policy_t policy;
406        err_status_t srtpCreateStatus;
407        err_status_t addStreamStatus;
408        OrtpZrtpContext *userData = user_data(ctx);
409
410        ortp_message("ZRTP secrets for %s are ready; auth tag len is %i",
411                     (part == ForSender) ? "sender" : "receiver",secrets->srtpAuthTagLen);
412
413        // Get authentication and cipher algorithms in srtp format
414        if (secrets->authAlgorithm != zrtp_Sha1) {
415                ortp_fatal("unsupported authentication algorithm by srtp");
416        }
417
418        if (secrets->symEncAlgorithm != zrtp_Aes) {
419                ortp_fatal("unsupported cipher algorithm by srtp");
420        }
421
422        /*
423         * Don't use crypto_policy_set_from_profile_for_rtp(), it is totally buggy.
424         */
425        memset(&policy,0,sizeof(policy));
426
427        if (secrets->srtpAuthTagLen == 32){
428                crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
429                crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp);
430        }else if (secrets->srtpAuthTagLen == 80){
431                crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
432                crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
433        }else{
434                ortp_fatal("unsupported auth tag len");
435        }
436
437        if (part == ForSender) {
438                srtpCreateStatus=srtp_create(&userData->srtpSend, NULL);
439                policy.ssrc.type=ssrc_specific;
440                policy.ssrc.value=userData->session->snd.ssrc; // us
441                policy.key=key_with_salt(secrets, secrets->role);
442                addStreamStatus=srtp_add_stream(userData->srtpSend, &policy);
443        } else { //if (part == ForReceiver)
444                srtpCreateStatus=srtp_create(&userData->srtpRecv, NULL);
445                policy.ssrc.type = ssrc_any_inbound; /*we don't know the incoming ssrc will be */
446                int32_t peerRole=secrets->role == Initiator ? Responder : Initiator;
447                policy.key=key_with_salt(secrets,peerRole);
448                addStreamStatus=srtp_add_stream(userData->srtpRecv, &policy);
449        }
450
451        ortp_free(policy.key);
452
453        if (srtpCreateStatus != err_status_ok) {
454                ortp_error("ZRTP Error %u during creation of SRTP context for %s",
455                        srtpCreateStatus, (part == ForSender) ? "sender" : "receiver");
456                return 0;
457        }
458        if (addStreamStatus != err_status_ok) {
459                ortp_error("ZRTP Error %u during addition of SRTP stream for %s",
460                        addStreamStatus, (part == ForSender) ? "sender" : "receiver");
461                return 0;
462        }
463        return 1;
464}
465
466
467
468
469/**
470 * Switch off the security for the defined part.
471 *
472 * @param ctx
473 *    Pointer to the opaque ZrtpContext structure.
474 * @param part Defines for which part (sender or receiver) to
475 *    switch off security
476 */
477static void ozrtp_srtpSecretsOff (ZrtpContext* ctx, int32_t part ) {
478        OrtpZrtpContext *userData = user_data(ctx);
479
480        if (userData->srtpRecv != NULL) {
481                srtp_dealloc(userData->srtpRecv);
482                userData->srtpRecv=NULL;
483        }
484
485        if (userData->srtpSend != NULL) {
486                srtp_dealloc(userData->srtpSend);
487                userData->srtpSend=NULL;
488        }
489
490        ortp_message("ZRTP secrets off");
491}
492
493/**
494 * Switch on the security.
495 *
496 * ZRTP calls this method after it has computed the SAS and check
497 * if it is verified or not. In addition ZRTP provides information
498 * about the cipher algorithm and key length for the SRTP session.
499 *
500 * This method must enable SRTP processing if it was not enabled
501 * during sertSecretsReady().
502 *
503 * @param ctx
504 *    Pointer to the opaque ZrtpContext structure.
505 * @param c The name of the used cipher algorithm and mode, or
506 *    NULL
507 *
508 * @param s The SAS string
509 *
510 * @param verified if <code>verified</code> is true then SAS was
511 *    verified by both parties during a previous call.
512 */
513static void ozrtp_rtpSecretsOn (ZrtpContext* ctx, char* c, char* s, int32_t verified ){
514//      OrtpZrtpContext *userData = user_data(ctx);
515
516        // srtp processing is enabled in SecretsReady fuction when receiver secrets are ready
517        // Indeed, the secrets on is called before both parts are given to secretsReady.
518
519        OrtpEventData *eventData;
520        OrtpEvent *ev;
521        ev=ortp_event_new(ORTP_EVENT_ZRTP_SAS_READY);
522        eventData=ortp_event_get_data(ev);
523        memcpy(eventData->info.zrtp_sas.sas,s,4);
524        eventData->info.zrtp_sas.sas[4]=0;
525        eventData->info.zrtp_sas.verified=(verified != 0) ? TRUE : FALSE;
526        rtp_session_dispatch_event(user_data(ctx)->session, ev);
527        ortp_message("ZRTP secrets on: SAS is %s previously verified %s - algo %s", s, verified == 0 ? "no" : "yes", c);
528}
529
530
531/**
532 *
533 * According to the ZRTP specification the user must be informed about
534 * a GoClear request because the ZRTP implementation switches off security
535 * if it could authenticate the GoClear packet.
536 *
537 * <b>Note:</b> GoClear is not yet implemented in GNU ZRTP.
538 *
539 * @param ctx
540 *    Pointer to the opaque ZrtpContext structure.
541 */
542static void ozrtp_handleGoClear(ZrtpContext* ctx) {
543        ortp_fatal("not implemented");
544}
545
546/**
547 * Handle ZRTP negotiation failed.
548 *
549 * ZRTP calls this method in case ZRTP negotiation failed. The
550 * parameters show the severity as well as the reason.
551 *
552 * @param ctx
553 *    Pointer to the opaque ZrtpContext structure.
554 * @param severity
555 *     This defines the message's severity
556 * @param subCode
557 *     The subcode identifying the reason.
558 * @see ZrtpCodes#MessageSeverity
559 */
560static void ozrtp_zrtpNegotiationFailed (ZrtpContext* ctx, int32_t severity, int32_t subCode ){
561        ozrtp_sendInfo(ctx, severity, subCode);
562        // FIXME: necessary?
563}
564
565/**
566 * ZRTP calls this method if the other side does not support ZRTP.
567 *
568 * @param ctx
569 *    Pointer to the opaque ZrtpContext structure.
570 * If the other side does not answer the ZRTP <em>Hello</em> packets then
571 * ZRTP calls this method,
572 *
573 */
574static void ozrtp_zrtpNotSuppOther(ZrtpContext* ctx) {
575        // FIXME: do nothing
576}
577
578/**
579 * Enter synchronization mutex.
580 *
581 * GNU ZRTP requires one mutex to synchronize its
582 * processing. Because mutex implementations depend on the
583 * underlying infrastructure, for example operating system or
584 * thread implementation, GNU ZRTP delegates mutex handling to the
585 * specific part of its implementation.
586 *
587 * @param ctx
588 *    Pointer to the opaque ZrtpContext structure.
589 */
590static void ozrtp_synchEnter(ZrtpContext* ctx){
591        ortp_mutex_lock(&user_data(ctx)->mutex);
592}
593
594/**
595 * Leave synchronization mutex.
596 *
597 * @param ctx
598 *    Pointer to the opaque ZrtpContext structure.
599 */
600static void ozrtp_synchLeave(ZrtpContext* ctx){
601        ortp_mutex_unlock(&user_data(ctx)->mutex);
602}
603
604
605static inline uint32_t get_rtcp_ssrc(uint8_t *rtp) {
606        return ntohl(*(uint32_t*)(rtp+4));
607
608}
609static int ozrtp_generic_sendto(stream_type stream, RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){
610        int slen;
611        err_status_t err;
612        ortp_socket_t socket;
613
614        ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
615        OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;
616
617
618        if (stream == rtp_stream) {
619                socket= t->session->rtp.socket;
620        } else {
621                socket= t->session->rtcp.socket;
622        }
623
624        if (userData->srtpSend == NULL || !zrtp_inState(zrtpContext, SecureState)) {
625                int size;
626                msgpullup(m,-1);
627                size=msgdsize(m);
628                return sendto(socket,(void*)m->b_rptr,size,flags,to,tolen);
629        }
630        slen=msgdsize(m);
631        // Protect with srtp
632        /* enlarge the buffer for srtp to write its data */
633        msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES);
634        if (stream == rtp_stream) {
635                err=srtp_protect(userData->srtpSend,m->b_rptr,&slen);
636        } else {
637                err=srtp_protect_rtcp(userData->srtpSend,m->b_rptr,&slen);
638        }
639        if (err==err_status_ok){
640                return sendto(socket,(void*)m->b_rptr,slen,flags,to,tolen);
641        } else {
642                ortp_error("srtp_protect() failed with status %d", err);
643        }
644        return -1;
645}
646
647static int ozrtp_rtcp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){
648        return ozrtp_generic_sendto(rtcp_stream,t,m,flags,to,tolen);
649}
650
651static int ozrtp_rtp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){
652        return ozrtp_generic_sendto(rtp_stream,t,m,flags,to,tolen);
653}
654
655
656static int ozrtp_rtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
657        int rlen;
658
659        ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
660        OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;
661
662
663        // Do extra stuff first
664        check_timer(zrtpContext, userData);
665
666
667        // Check if something to receive
668        rlen=rtp_session_rtp_recv_abstract(t->session->rtp.socket,m,flags,from,fromlen);
669        if (rlen<=0) {
670                // nothing was received or error: pass the information to caller
671                return rlen;
672        }
673
674        uint8_t* rtp = m->b_rptr;
675        int rtpVersion = ((rtp_header_t*)rtp)->version;
676
677        // If plain or secured RTP
678        if (rtpVersion == 2) {
679                if (userData->srtpRecv != NULL && zrtp_inState(zrtpContext, SecureState)) {
680                        // probably srtp packet, unprotect
681                        err_status_t err = srtp_unprotect(userData->srtpRecv,m->b_wptr,&rlen);
682                        if (err != err_status_ok) {
683                                ortp_warning("srtp_unprotect failed; packet may be plain RTP");
684                        }
685                }
686                // in both cases (RTP plain and deciphered srtp)
687                return rlen;
688        }
689
690
691        // if ZRTP packet, send to engine
692        uint32_t *magicField=(uint32_t *)(rtp + 4);
693        if (rlen >= ZRTP_MIN_MSG_LENGTH && rtpVersion==0 && ntohl(*magicField) == ZRTP_MAGIC) {
694                print_zrtp_packet("received", rtp);
695                uint8_t *ext_header = rtp+ZRTP_MESSAGE_OFFSET;
696                uint16_t ext_length = get_zrtp_message_length(ext_header);
697                char messageType[9];
698                parseZrtpMessageType(messageType, ext_header);
699
700                // Check max length
701                if (rlen < 12 + ext_length + 4) {
702                        ortp_warning("Received malformed ZRTP-like packet: size %d (expected %d)", rlen, 12 + ext_length + 4);
703                        return 0;
704                }
705
706                // Check sequence number
707                uint16_t seq_number = get_rtp_seqnumber(rtp);
708                if (userData->last_recv_zrtp_seq_number != 0 && seq_number <= userData->last_recv_zrtp_seq_number) {
709                        // Discard out of order ZRTP packet
710                        ortp_message("Discarding received out of order zrtp packet: %d (expected >%d)",
711                                        seq_number, userData->last_recv_zrtp_seq_number);
712                        return 0;
713                }
714
715
716                // Check packet checksum
717                uint32_t rcv_crc = get_zrtp_packet_crc((uint32_t*)rtp, ext_length);
718                uint32_t zrtp_total_packet_length = ZRTP_MESSAGE_OFFSET + 4*ext_length + 4;
719                if (!zrtp_CheckCksum(rtp, zrtp_total_packet_length-CRC_SIZE, rcv_crc)) {
720                        ortp_warning("Bad ZRTP packet checksum %u total %u", rcv_crc, zrtp_total_packet_length);
721                        return 0;
722                }
723
724                uint32_t peerssrc = ntohl(*(uint32_t*)(rtp+8));
725                zrtp_processZrtpMessage(zrtpContext, ext_header, peerssrc);
726                userData->last_recv_zrtp_seq_number=seq_number;
727                return 0;
728                }
729        else {
730                // Not a ZRTP packet, accept it
731                return rlen;
732        }
733}
734
735
736
737static int ozrtp_rtcp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
738        ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
739        OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;
740
741        int rlen = rtp_session_rtp_recv_abstract(t->session->rtcp.socket,m,flags,from,fromlen);
742        if (rlen<=0) {
743                // nothing was received or error: pass the information to caller
744                return rlen;
745        }
746
747        uint8_t *rtcp = m->b_wptr;
748        int version = ((rtcp_common_header_t *)rtcp)->version;
749        if (version == 2 && userData->srtpRecv != NULL && zrtp_inState(zrtpContext, SecureState)) {
750                err_status_t err = srtp_unprotect_rtcp(userData->srtpRecv,m->b_wptr,&rlen);
751                if (err != err_status_ok) {
752                        ortp_error("srtp_unprotect failed %d ; packet discarded (may be plain RTCP)", err);
753                        return 0;
754                }
755        }
756
757        return rlen;
758}
759
760
761static ortp_socket_t ozrtp_rtp_getsocket(RtpTransport *t){
762  return t->session->rtp.socket;
763}
764
765static ortp_socket_t ozrtp_rtcp_getsocket(RtpTransport *t){
766  return t->session->rtcp.socket;
767}
768
769static OrtpZrtpContext* createUserData(ZrtpContext *context) {
770        OrtpZrtpContext *userData=ortp_new0(OrtpZrtpContext,1);
771        userData->zrtpContext=context;
772        userData->timerWillTriggerAt=0;
773        userData->last_recv_zrtp_seq_number=0;
774        userData->last_sent_zrtp_seq_number=rand()+1; // INT_MAX+1 (signed)
775
776        userData->srtpRecv=NULL;
777        userData->srtpSend=NULL;
778        ortp_mutex_init(&userData->mutex,NULL);
779
780        memset(&userData->zrtp_cb,0,sizeof(userData->zrtp_cb));
781        userData->zrtp_cb.zrtp_activateTimer=&ozrtp_activateTimer;
782        userData->zrtp_cb.zrtp_cancelTimer=&ozrtp_cancelTimer;
783        userData->zrtp_cb.zrtp_handleGoClear=&ozrtp_handleGoClear;
784        userData->zrtp_cb.zrtp_rtpSecretsOn=&ozrtp_rtpSecretsOn;
785        userData->zrtp_cb.zrtp_sendDataZRTP=&ozrtp_sendDataZRTP;
786        userData->zrtp_cb.zrtp_sendInfo=&ozrtp_sendInfo;
787        userData->zrtp_cb.zrtp_srtpSecretsOff=&ozrtp_srtpSecretsOff;
788        userData->zrtp_cb.zrtp_srtpSecretsReady=&ozrtp_srtpSecretsReady;
789        userData->zrtp_cb.zrtp_synchEnter=&ozrtp_synchEnter;
790        userData->zrtp_cb.zrtp_synchLeave=&ozrtp_synchLeave;
791        userData->zrtp_cb.zrtp_zrtpNegotiationFailed=&ozrtp_zrtpNegotiationFailed;
792        userData->zrtp_cb.zrtp_zrtpNotSuppOther=&ozrtp_zrtpNotSuppOther;
793
794        return userData;
795}
796
797//static void initContext() {
798        // Configure algorithms
799        //zrtp_confClear(context);
800        /* FIXMe use default ones as these methods require some unknown char*
801        zrtp_addAlgo(context,zrtp_CipherAlgorithm,zrtp_Aes);
802        zrtp_addAlgo(context,zrtp_HashAlgorithm,zrtp_Sha1);*/
803        // CF zrtp_InitializeConfig
804//}
805
806static void ortp_zrtp_configure(ZrtpContext *context){
807        zrtp_InitializeConfig(context);
808        zrtp_setMandatoryOnly(context);
809        zrtp_setTrustedMitM(context,FALSE);//because it is uninitialized in zrtpcpp.
810        zrtp_setSasSignature(context,FALSE);//because it is uninitialized in zrtpcpp.
811}
812
813static OrtpZrtpContext* ortp_zrtp_configure_context(OrtpZrtpContext *userData, RtpSession *s, OrtpZrtpParams *params) {
814        ZrtpContext *context=userData->zrtpContext;
815
816
817        if (s->rtp.tr || s->rtcp.tr)
818                ortp_warning("Overwriting rtp or rtcp transport with ZRTP one");
819
820        userData->rtpt.data=context;
821        userData->rtpt.t_getsocket=ozrtp_rtp_getsocket;
822        userData->rtpt.t_sendto=ozrtp_rtp_sendto;
823        userData->rtpt.t_recvfrom=ozrtp_rtp_recvfrom;
824
825        userData->rtcpt.data=context;
826        userData->rtcpt.t_getsocket=ozrtp_rtcp_getsocket;
827        userData->rtcpt.t_sendto=ozrtp_rtcp_sendto;
828        userData->rtcpt.t_recvfrom=ozrtp_rtcp_recvfrom;
829
830        rtp_session_set_transports(s, &userData->rtpt, &userData->rtcpt);
831
832        ortp_message("Starting ZRTP engine");
833        zrtp_setEnrollmentMode(context,FALSE);//because it is uninitialized in zrtpcpp.
834       
835        zrtp_startZrtpEngine(context);
836
837        return userData;
838}
839
840OrtpZrtpContext* ortp_zrtp_context_new(RtpSession *s, OrtpZrtpParams *params){
841        ZrtpContext *context = zrtp_CreateWrapper();
842        OrtpZrtpContext *userData=createUserData(context);
843        userData->session=s;
844        ortp_zrtp_configure(context);
845        ortp_message("Initialized ZRTP context");
846        zrtp_initializeZrtpEngine(context, &userData->zrtp_cb, userAgentStr, params->zid_file, userData, 0);
847        return ortp_zrtp_configure_context(userData,s,params);
848}
849
850OrtpZrtpContext* ortp_zrtp_multistream_new(OrtpZrtpContext* activeContext, RtpSession *s, OrtpZrtpParams *params) {
851        int32_t length;
852        char *multiparams=NULL;
853        int i=0;
854       
855        if (!zrtp_isMultiStreamAvailable(activeContext->zrtpContext)) {
856                ortp_warning("could't add stream: mutlistream not supported by peer");
857        }
858
859        if (zrtp_isMultiStream(activeContext->zrtpContext)) {
860                ortp_fatal("Error: should derive multistream from DH or preshared modes only");
861        }
862
863        multiparams=zrtp_getMultiStrParams(activeContext->zrtpContext, &length);
864       
865        ortp_message("ZRTP multiparams length is %d", length);
866        for (;i<length;i++) {
867                ortp_message("%d", multiparams[i]);
868        }
869
870        ortp_message("Initializing ZRTP context");
871        ZrtpContext *context = zrtp_CreateWrapper();
872        OrtpZrtpContext *userData=createUserData(context);
873        userData->session=s;
874        ortp_zrtp_configure(context);
875       
876        zrtp_initializeZrtpEngine(context, &userData->zrtp_cb, userAgentStr, params->zid_file, userData, 0);
877
878        ortp_message("setting zrtp_setMultiStrParams");
879        zrtp_setMultiStrParams(context,multiparams,length);
880
881        return ortp_zrtp_configure_context(userData,s,params);
882}
883
884bool_t ortp_zrtp_available(){return TRUE;}
885
886
887
888void ortp_zrtp_sas_verified(OrtpZrtpContext* ctx){
889        zrtp_SASVerified(ctx->zrtpContext);
890}
891
892void ortp_zrtp_sas_reset_verified(OrtpZrtpContext* ctx){
893        zrtp_resetSASVerified(ctx->zrtpContext);
894}
895
896void ortp_zrtp_context_destroy(OrtpZrtpContext *ctx) {
897        ortp_message("Stopping ZRTP context");
898        zrtp_stopZrtpEngine(ctx->zrtpContext);
899
900        ortp_message("Destroying ZRTP wrapper");
901        zrtp_DestroyWrapper(ctx->zrtpContext);
902
903        ortp_message("Destroying ORTP-ZRTP mutex");
904        ortp_mutex_destroy(&ctx->mutex);
905
906        ortp_message("Destroying SRTP contexts");
907        if (ctx->srtpSend != NULL) srtp_dealloc(ctx->srtpSend);
908        if (ctx->srtpRecv != NULL) srtp_dealloc(ctx->srtpRecv);
909
910        ortp_message("ORTP-ZRTP context destroyed");
911}
912
913
914
915#else
916
917
918OrtpZrtpContext* ortp_zrtp_context_new(RtpSession *s, OrtpZrtpParams *params){
919        ortp_message("ZRTP is disabled - not implemented yet");
920        return NULL;
921}
922
923OrtpZrtpContext* ortp_zrtp_multistream_new(OrtpZrtpContext* activeContext, RtpSession *s, OrtpZrtpParams *params) {
924        ortp_message("ZRTP is disabled - not implemented yet - not adding stream");
925        return NULL;
926}
927
928bool_t ortp_zrtp_available(){return FALSE;}
929void ortp_zrtp_sas_verified(OrtpZrtpContext* ctx){}
930void ortp_zrtp_sas_reset_verified(OrtpZrtpContext* ctx){}
931void ortp_zrtp_context_destroy(OrtpZrtpContext *ctx){}
932
933#endif
934
935
Note: See TracBrowser for help on using the repository browser.