Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / p2p / socket_host.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/p2p/socket_host.h"
6
7 #include "base/sys_byteorder.h"
8 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
9 #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
10 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
11 #include "crypto/hmac.h"
12 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
13 #include "third_party/libjingle/source/talk/base/byteorder.h"
14 #include "third_party/libjingle/source/talk/base/messagedigest.h"
15 #include "third_party/libjingle/source/talk/p2p/base/stun.h"
16
17 namespace {
18
19 const uint32 kStunMagicCookie = 0x2112A442;
20 const int kMinRtpHdrLen = 12;
21 const int kRtpExtnHdrLen = 4;
22 const int kDtlsRecordHeaderLen = 13;
23 const int kTurnChannelHdrLen = 4;
24 const int kAbsSendTimeExtnLen = 3;
25 const int kOneByteHdrLen = 1;
26
27 // Fake auth tag written by the render process if external authentication is
28 // enabled. HMAC in packet will be compared against this value before updating
29 // packet with actual HMAC value.
30 static const unsigned char kFakeAuthTag[10] = {
31     0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd
32 };
33
34 bool IsTurnChannelData(const char* data) {
35   return ((*data & 0xC0) == 0x40);
36 }
37
38 bool IsDtlsPacket(const char* data, int len) {
39   const uint8* u = reinterpret_cast<const uint8*>(data);
40   return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
41 }
42
43 bool IsRtcpPacket(const char* data) {
44   int type = (static_cast<uint8>(data[1]) & 0x7F);
45   return (type >= 64 && type < 96);
46 }
47
48 bool IsTurnSendIndicationPacket(const char* data) {
49   uint16 type = talk_base::GetBE16(data);
50   return (type == cricket::TURN_SEND_INDICATION);
51 }
52
53 bool IsRtpPacket(const char* data, int len) {
54   return ((*data & 0xC0) == 0x80);
55 }
56
57 // Verifies rtp header and message length.
58 bool ValidateRtpHeader(char* rtp, int length) {
59   int cc_count = rtp[0] & 0x0F;
60   int rtp_hdr_len_without_extn = kMinRtpHdrLen + 4 * cc_count;
61   if (rtp_hdr_len_without_extn > length) {
62     return false;
63   }
64
65   // If extension bit is not set, we are done with header processing, as input
66   // length is verified above.
67   if (!(rtp[0] & 0x10)) {
68     return true;
69   }
70
71   rtp += rtp_hdr_len_without_extn;
72
73   // Getting extension profile length.
74   // Length is in 32 bit words.
75   uint16 extn_length = talk_base::GetBE16(rtp + 2) * 4;
76
77   // Verify input length against total header size.
78   if (rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length > length) {
79     return false;
80   }
81   return true;
82 }
83
84 void UpdateAbsSendTimeExtnValue(char* extn_data, int len,
85                                 uint32 abs_send_time) {
86   // Absolute send time in RTP streams.
87   //
88   // The absolute send time is signaled to the receiver in-band using the
89   // general mechanism for RTP header extensions [RFC5285]. The payload
90   // of this extension (the transmitted value) is a 24-bit unsigned integer
91   // containing the sender's current time in seconds as a fixed point number
92   // with 18 bits fractional part.
93   //
94   // The form of the absolute send time extension block:
95   //
96   //    0                   1                   2                   3
97   //    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
98   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99   //   |  ID   | len=2 |              absolute send time               |
100   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101   DCHECK_EQ(len, kAbsSendTimeExtnLen);
102   // Now() has resolution ~1-15ms, using HighResNow(). But it is warned not to
103   // use it unless necessary, as it is expensive than Now().
104   uint32 now_second = abs_send_time;
105   if (!now_second) {
106     uint64 now_us =
107         (base::TimeTicks::HighResNow() - base::TimeTicks()).InMicroseconds();
108     // Convert second to 24-bit unsigned with 18 bit fractional part
109     now_second =
110         ((now_us << 18) / base::Time::kMicrosecondsPerSecond) & 0x00FFFFFF;
111   }
112   // TODO(mallinath) - Add SetBE24 to byteorder.h in libjingle.
113   extn_data[0] = static_cast<uint8>(now_second >> 16);
114   extn_data[1] = static_cast<uint8>(now_second >> 8);
115   extn_data[2] = static_cast<uint8>(now_second);
116 }
117
118 // Assumes |len| is actual packet length + tag length. Updates HMAC at end of
119 // the RTP packet.
120 void UpdateRtpAuthTag(char* rtp, int len,
121                       const talk_base::PacketOptions& options) {
122   // If there is no key, return.
123   if (options.packet_time_params.srtp_auth_key.empty())
124     return;
125
126   size_t tag_length = options.packet_time_params.srtp_auth_tag_len;
127   char* auth_tag = rtp + (len - tag_length);
128
129   // We should have a fake HMAC value @ auth_tag.
130   DCHECK_EQ(0, memcmp(auth_tag, kFakeAuthTag, tag_length));
131
132   crypto::HMAC hmac(crypto::HMAC::SHA1);
133   if (!hmac.Init(reinterpret_cast<const unsigned char*>(
134         &options.packet_time_params.srtp_auth_key[0]),
135         options.packet_time_params.srtp_auth_key.size())) {
136     NOTREACHED();
137     return;
138   }
139
140   if (hmac.DigestLength() < tag_length) {
141     NOTREACHED();
142     return;
143   }
144
145   // Copy ROC after end of rtp packet.
146   memcpy(auth_tag, &options.packet_time_params.srtp_packet_index, 4);
147   // Authentication of a RTP packet will have RTP packet + ROC size.
148   int auth_required_length = len - tag_length + 4;
149
150   unsigned char output[64];
151   if (!hmac.Sign(base::StringPiece(rtp, auth_required_length),
152                  output, sizeof(output))) {
153     NOTREACHED();
154     return;
155   }
156   // Copy HMAC from output to packet. This is required as auth tag length
157   // may not be equal to the actual HMAC length.
158   memcpy(auth_tag, output, tag_length);
159 }
160
161 }  // namespace
162
163 namespace content {
164
165 namespace packet_processing_helpers {
166
167 bool ApplyPacketOptions(char* data, int length,
168                         const talk_base::PacketOptions& options,
169                         uint32 abs_send_time) {
170   DCHECK(data != NULL);
171   DCHECK(length > 0);
172   // if there is no valid |rtp_sendtime_extension_id| and |srtp_auth_key| in
173   // PacketOptions, nothing to be updated in this packet.
174   if (options.packet_time_params.rtp_sendtime_extension_id == -1 &&
175       options.packet_time_params.srtp_auth_key.empty()) {
176     return true;
177   }
178
179   DCHECK(!IsDtlsPacket(data, length));
180   DCHECK(!IsRtcpPacket(data));
181
182   // If there is a srtp auth key present then packet must be a RTP packet.
183   // RTP packet may have been wrapped in a TURN Channel Data or
184   // TURN send indication.
185   int rtp_start_pos;
186   int rtp_length;
187   if (!GetRtpPacketStartPositionAndLength(
188       data, length, &rtp_start_pos, &rtp_length)) {
189     // This method should never return false.
190     NOTREACHED();
191     return false;
192   }
193
194   // Skip to rtp packet.
195   char* start = data + rtp_start_pos;
196   // If packet option has non default value (-1) for sendtime extension id,
197   // then we should parse the rtp packet to update the timestamp. Otherwise
198   // just calculate HMAC and update packet with it.
199   if (options.packet_time_params.rtp_sendtime_extension_id != -1) {
200     UpdateRtpAbsSendTimeExtn(
201         start, rtp_length,
202         options.packet_time_params.rtp_sendtime_extension_id, abs_send_time);
203   }
204
205   UpdateRtpAuthTag(start, rtp_length, options);
206   return true;
207 }
208
209 bool GetRtpPacketStartPositionAndLength(
210     char* packet, int length, int* rtp_start_pos, int* rtp_packet_length) {
211   int rtp_begin, rtp_length;
212   if (IsTurnChannelData(packet)) {
213     // Turn Channel Message header format.
214     //   0                   1                   2                   3
215     //  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
216     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217     // |         Channel Number        |            Length             |
218     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219     // |                                                               |
220     // /                       Application Data                        /
221     // /                                                               /
222     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
223     if (length < kTurnChannelHdrLen) {
224       return false;
225     }
226
227     rtp_begin = kTurnChannelHdrLen;
228     rtp_length = talk_base::GetBE16(&packet[2]);
229     if (length < rtp_length + kTurnChannelHdrLen) {
230       return false;
231     }
232   } else if (IsTurnSendIndicationPacket(packet)) {
233     if (length <= P2PSocketHost::kStunHeaderSize) {
234       // Message must be greater than 20 bytes, if it's carrying any payload.
235       return false;
236     }
237     // Validate STUN message length.
238     int stun_msg_len = talk_base::GetBE16(&packet[2]);
239     if (stun_msg_len + P2PSocketHost::kStunHeaderSize != length) {
240       return false;
241     }
242
243     // First skip mandatory stun header which is of 20 bytes.
244     rtp_begin = P2PSocketHost::kStunHeaderSize;
245     // Loop through STUN attributes until we find STUN DATA attribute.
246     char* start = packet + rtp_begin;
247     bool data_attr_present = false;
248     while ((packet + rtp_begin) - start < stun_msg_len) {
249       // Keep reading STUN attributes until we hit DATA attribute.
250       // Attribute will be a TLV structure.
251       // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
252       // |         Type                  |            Length             |
253       // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
254       // |                         Value (variable)                ....
255       // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
256       // The value in the length field MUST contain the length of the Value
257       // part of the attribute, prior to padding, measured in bytes.  Since
258       // STUN aligns attributes on 32-bit boundaries, attributes whose content
259       // is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of
260       // padding so that its value contains a multiple of 4 bytes.  The
261       // padding bits are ignored, and may be any value.
262       uint16 attr_type, attr_length;
263       // Getting attribute type and length.
264       attr_type = talk_base::GetBE16(&packet[rtp_begin]);
265       attr_length = talk_base::GetBE16(
266           &packet[rtp_begin + sizeof(attr_type)]);
267       // Checking for bogus attribute length.
268       if (length < attr_length + rtp_begin) {
269         return false;
270       }
271
272       if (attr_type != cricket::STUN_ATTR_DATA) {
273         rtp_begin += sizeof(attr_type) + sizeof(attr_length) + attr_length;
274         if ((attr_length % 4) != 0) {
275           rtp_begin += (4 - (attr_length % 4));
276         }
277         continue;
278       }
279
280       data_attr_present = true;
281       rtp_begin += 4;  // Skip STUN_DATA_ATTR header.
282       rtp_length = attr_length;
283       // One final check of length before exiting.
284       if (length < rtp_length + rtp_begin) {
285         return false;
286       }
287       // We found STUN_DATA_ATTR. We can skip parsing rest of the packet.
288       break;
289     }
290
291     if (!data_attr_present) {
292       // There is no data attribute present in the message. We can't do anything
293       // with the message.
294       return false;
295     }
296
297   } else {
298     // This is a raw RTP packet.
299     rtp_begin = 0;
300     rtp_length = length;
301   }
302
303   // Making sure we have a valid RTP packet at the end.
304   if (!(rtp_length < kMinRtpHdrLen) &&
305       IsRtpPacket(packet + rtp_begin, rtp_length) &&
306       ValidateRtpHeader(packet + rtp_begin, rtp_length)) {
307     *rtp_start_pos = rtp_begin;
308     *rtp_packet_length = rtp_length;
309     return true;
310   }
311   return false;
312 }
313
314 // ValidateRtpHeader must be called before this method to make sure, we have
315 // a sane rtp packet.
316 bool UpdateRtpAbsSendTimeExtn(char* rtp, int length,
317                               int extension_id, uint32 abs_send_time) {
318   //  0                   1                   2                   3
319   //  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
320   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
321   // |V=2|P|X|  CC   |M|     PT      |       sequence number         |
322   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323   // |                           timestamp                           |
324   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
325   // |           synchronization source (SSRC) identifier            |
326   // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
327   // |            contributing source (CSRC) identifiers             |
328   // |                             ....                              |
329   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330
331   // Return if extension bit is not set.
332   if (!(rtp[0] & 0x10)) {
333     return true;
334   }
335
336   int cc_count = rtp[0] & 0x0F;
337   int rtp_hdr_len_without_extn = kMinRtpHdrLen + 4 * cc_count;
338
339   rtp += rtp_hdr_len_without_extn;
340
341   // Getting extension profile ID and length.
342   uint16 profile_id = talk_base::GetBE16(rtp);
343   // Length is in 32 bit words.
344   uint16 extn_length = talk_base::GetBE16(rtp + 2) * 4;
345
346   rtp += kRtpExtnHdrLen;  // Moving past extn header.
347
348   bool found = false;
349   // WebRTC is using one byte header extension.
350   // TODO(mallinath) - Handle two byte header extension.
351   if (profile_id == 0xBEDE) {  // OneByte extension header
352     //  0
353     //  0 1 2 3 4 5 6 7
354     // +-+-+-+-+-+-+-+-+
355     // |  ID   |  len  |
356     // +-+-+-+-+-+-+-+-+
357
358     //  0                   1                   2                   3
359     //  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
360     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361     // |       0xBE    |    0xDE       |           length=3            |
362     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363     // |  ID   | L=0   |     data      |  ID   |  L=1  |   data...
364     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365     //       ...data   |    0 (pad)    |    0 (pad)    |  ID   | L=3   |
366     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367     // |                          data                                 |
368     // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369     char* extn_start = rtp;
370     while (rtp - extn_start < extn_length) {
371       const int id = (*rtp & 0xF0) >> 4;
372       const int len = (*rtp & 0x0F) + 1;
373       // The 4-bit length is the number minus one of data bytes of this header
374       // extension element following the one-byte header.
375       if (id == extension_id) {
376         UpdateAbsSendTimeExtnValue(rtp + kOneByteHdrLen, len, abs_send_time);
377         found = true;
378         break;
379       }
380       rtp += kOneByteHdrLen + len;
381       // Counting padding bytes.
382       while ((*rtp == 0) && (rtp - extn_start < extn_length)) {
383         ++rtp;
384       }
385     }
386   }
387   return found;
388 }
389
390 }  // packet_processing_helpers
391
392 P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender,
393                              int id)
394     : message_sender_(message_sender),
395       id_(id),
396       state_(STATE_UNINITIALIZED) {
397 }
398
399 P2PSocketHost::~P2PSocketHost() { }
400
401 // Verifies that the packet |data| has a valid STUN header.
402 // static
403 bool P2PSocketHost::GetStunPacketType(
404     const char* data, int data_size, StunMessageType* type) {
405
406   if (data_size < kStunHeaderSize)
407     return false;
408
409   uint32 cookie = base::NetToHost32(*reinterpret_cast<const uint32*>(data + 4));
410   if (cookie != kStunMagicCookie)
411     return false;
412
413   uint16 length = base::NetToHost16(*reinterpret_cast<const uint16*>(data + 2));
414   if (length != data_size - kStunHeaderSize)
415     return false;
416
417   int message_type = base::NetToHost16(*reinterpret_cast<const uint16*>(data));
418
419   // Verify that the type is known:
420   switch (message_type) {
421     case STUN_BINDING_REQUEST:
422     case STUN_BINDING_RESPONSE:
423     case STUN_BINDING_ERROR_RESPONSE:
424     case STUN_SHARED_SECRET_REQUEST:
425     case STUN_SHARED_SECRET_RESPONSE:
426     case STUN_SHARED_SECRET_ERROR_RESPONSE:
427     case STUN_ALLOCATE_REQUEST:
428     case STUN_ALLOCATE_RESPONSE:
429     case STUN_ALLOCATE_ERROR_RESPONSE:
430     case STUN_SEND_REQUEST:
431     case STUN_SEND_RESPONSE:
432     case STUN_SEND_ERROR_RESPONSE:
433     case STUN_DATA_INDICATION:
434       *type = static_cast<StunMessageType>(message_type);
435       return true;
436
437     default:
438       return false;
439   }
440 }
441
442 // static
443 bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) {
444   return type == STUN_BINDING_REQUEST || type == STUN_BINDING_RESPONSE ||
445       type == STUN_ALLOCATE_REQUEST || type == STUN_ALLOCATE_RESPONSE;
446 }
447
448 // static
449 P2PSocketHost* P2PSocketHost::Create(
450     IPC::Sender* message_sender, int id, P2PSocketType type,
451     net::URLRequestContextGetter* url_context,
452     P2PMessageThrottler* throttler) {
453   switch (type) {
454     case P2P_SOCKET_UDP:
455       return new P2PSocketHostUdp(message_sender, id, throttler);
456     case P2P_SOCKET_TCP_SERVER:
457       return new P2PSocketHostTcpServer(
458           message_sender, id, P2P_SOCKET_TCP_CLIENT);
459
460     case P2P_SOCKET_STUN_TCP_SERVER:
461       return new P2PSocketHostTcpServer(
462           message_sender, id, P2P_SOCKET_STUN_TCP_CLIENT);
463
464     case P2P_SOCKET_TCP_CLIENT:
465     case P2P_SOCKET_SSLTCP_CLIENT:
466     case P2P_SOCKET_TLS_CLIENT:
467       return new P2PSocketHostTcp(message_sender, id, type, url_context);
468
469     case P2P_SOCKET_STUN_TCP_CLIENT:
470     case P2P_SOCKET_STUN_SSLTCP_CLIENT:
471     case P2P_SOCKET_STUN_TLS_CLIENT:
472       return new P2PSocketHostStunTcp(message_sender, id, type, url_context);
473   }
474
475   NOTREACHED();
476   return NULL;
477 }
478
479 }  // namespace content