Home | History | Annotate | Download | only in p2p
      1 // Copyright (c) 2014 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 <vector>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
     11 #include "net/base/ip_endpoint.h"
     12 #include "testing/gmock/include/gmock/gmock.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 static unsigned char kFakeTag[4] = { 0xba, 0xdd, 0xba, 0xdd };
     16 static unsigned char kTestKey[] = "12345678901234567890";
     17 static unsigned char kTestAstValue[3] = { 0xaa, 0xbb, 0xcc };
     18 
     19 // Rtp message with invalid length.
     20 static unsigned char kRtpMsgWithInvalidLength[] = {
     21   0x94, 0x00, 0x00, 0x00,
     22   0x00, 0x00, 0x00, 0x00,
     23   0xAA, 0xBB, 0xCC, 0XDD,  // SSRC
     24   0xDD, 0xCC, 0xBB, 0xAA   // Only 1 CSRC, but CC count is 4.
     25 };
     26 
     27 // Rtp message with single byte header extension, invalid extension length.
     28 static unsigned char kRtpMsgWithInvalidExtnLength[] = {
     29   0x90, 0x00, 0x00, 0x00,
     30   0x00, 0x00, 0x00, 0x00,
     31   0x00, 0x00, 0x00, 0x00,
     32   0xBE, 0xDE, 0x0A, 0x00   // Extn length - 0x0A00
     33 };
     34 
     35 // Valid rtp Message with 2 byte header extension.
     36 static unsigned char kRtpMsgWith2ByteExtnHeader[] = {
     37   0x90, 0x00, 0x00, 0x00,
     38   0x00, 0x00, 0x00, 0x00,
     39   0xAA, 0xBB, 0xCC, 0XDD,  // SSRC
     40   0x10, 0x00, 0x00, 0x01,  // 2 Byte header extension
     41   0x01, 0x00, 0x00, 0x00
     42 };
     43 
     44 // Stun Indication message with Zero length
     45 static unsigned char kTurnSendIndicationMsgWithNoAttributes[] = {
     46   0x00, 0x16, 0x00, 0x00,  // Zero length
     47   0x21, 0x12, 0xA4, 0x42,  // magic cookie
     48   '0', '1', '2', '3',      // transaction id
     49   '4', '5', '6', '7',
     50   '8', '9', 'a', 'b',
     51 };
     52 
     53 // Stun Send Indication message with invalid length in stun header.
     54 static unsigned char kTurnSendIndicationMsgWithInvalidLength[] = {
     55   0x00, 0x16, 0xFF, 0x00,  // length of 0xFF00
     56   0x21, 0x12, 0xA4, 0x42,  // magic cookie
     57   '0', '1', '2', '3',      // transaction id
     58   '4', '5', '6', '7',
     59   '8', '9', 'a', 'b',
     60 };
     61 
     62 // Stun Send Indication message with no DATA attribute in message.
     63 static unsigned char kTurnSendIndicatinMsgWithNoDataAttribute[] = {
     64   0x00, 0x16, 0x00, 0x08,  // length of
     65   0x21, 0x12, 0xA4, 0x42,  // magic cookie
     66   '0', '1', '2', '3',      // transaction id
     67   '4', '5', '6', '7',
     68   '8', '9', 'a', 'b',
     69   0x00, 0x20, 0x00, 0x04,  // Mapped address.
     70   0x00, 0x00, 0x00, 0x00
     71 };
     72 
     73 // A valid STUN indication message with a valid RTP header in data attribute
     74 // payload field and no extension bit set.
     75 static unsigned char kTurnSendIndicationMsgWithoutRtpExtension[] = {
     76   0x00, 0x16, 0x00, 0x18,  // length of
     77   0x21, 0x12, 0xA4, 0x42,  // magic cookie
     78   '0', '1', '2', '3',      // transaction id
     79   '4', '5', '6', '7',
     80   '8', '9', 'a', 'b',
     81   0x00, 0x20, 0x00, 0x04,  // Mapped address.
     82   0x00, 0x00, 0x00, 0x00,
     83   0x00, 0x13, 0x00, 0x0C,  // Data attribute.
     84   0x80, 0x00, 0x00, 0x00,  // RTP packet.
     85   0x00, 0x00, 0x00, 0x00,
     86   0x00, 0x00, 0x00, 0x00,
     87 };
     88 
     89 // A valid STUN indication message with a valid RTP header and a extension
     90 // header.
     91 static unsigned char kTurnSendIndicationMsgWithAbsSendTimeExtension[] = {
     92   0x00, 0x16, 0x00, 0x24,  // length of
     93   0x21, 0x12, 0xA4, 0x42,  // magic cookie
     94   '0', '1', '2', '3',      // transaction id
     95   '4', '5', '6', '7',
     96   '8', '9', 'a', 'b',
     97   0x00, 0x20, 0x00, 0x04,  // Mapped address.
     98   0x00, 0x00, 0x00, 0x00,
     99   0x00, 0x13, 0x00, 0x18,  // Data attribute.
    100   0x90, 0x00, 0x00, 0x00,  // RTP packet.
    101   0x00, 0x00, 0x00, 0x00,
    102   0x00, 0x00, 0x00, 0x00,
    103   0xBE, 0xDE, 0x00, 0x02,
    104   0x22, 0xaa, 0xbb, 0xcc,
    105   0x32, 0xaa, 0xbb, 0xcc,
    106 };
    107 
    108 // A valid TURN channel header, but not RTP packet.
    109 static unsigned char kTurnChannelMsgNoRtpPacket[] = {
    110   0x40, 0x00, 0x00, 0x04,
    111   0xaa, 0xbb, 0xcc, 0xdd,
    112 };
    113 
    114 // Turn ChannelMessage with zero length of payload.
    115 static unsigned char kTurnChannelMsgWithZeroLength[] = {
    116   0x40, 0x00, 0x00, 0x00
    117 };
    118 
    119 // Turn ChannelMessage, wrapping a RTP packet without extension.
    120 static unsigned char kTurnChannelMsgWithRtpPacket[] = {
    121   0x40, 0x00, 0x00, 0x0C,
    122   0x80, 0x00, 0x00, 0x00,  // RTP packet.
    123   0x00, 0x00, 0x00, 0x00,
    124   0x00, 0x00, 0x00, 0x00,
    125 };
    126 
    127 // Turn ChannelMessage, wrapping a RTP packet with AbsSendTime Extension.
    128 static unsigned char kTurnChannelMsgWithAbsSendTimeExtension[] = {
    129   0x40, 0x00, 0x00, 0x14,
    130   0x90, 0x00, 0x00, 0x00,  // RTP packet.
    131   0x00, 0x00, 0x00, 0x00,
    132   0x00, 0x00, 0x00, 0x00,
    133   0xBE, 0xDE, 0x00, 0x01,
    134   0x32, 0xaa, 0xbb, 0xcc,
    135 };
    136 
    137 // RTP packet with single byte extension header of length 4 bytes.
    138 // Extension id = 3 and length = 3
    139 static unsigned char kRtpMsgWithAbsSendTimeExtension[] = {
    140   0x90, 0x00, 0x00, 0x00,
    141   0x00, 0x00, 0x00, 0x00,
    142   0x00, 0x00, 0x00, 0x00,
    143   0xBE, 0xDE, 0x00, 0x02,
    144   0x22, 0x00, 0x02, 0x1c,
    145   0x32, 0xaa, 0xbb, 0xcc,
    146 };
    147 
    148 // Index of AbsSendTimeExtn data in message |kRtpMsgWithAbsSendTimeExtension|.
    149 static const int kAstIndexInRtpMsg = 21;
    150 
    151 namespace content {
    152 
    153 // This test verifies parsing of all invalid raw packets.
    154 TEST(P2PSocketHostTest, TestInvalidRawRtpMessages) {
    155   int start_pos = INT_MAX, rtp_length = INT_MAX;
    156   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    157       reinterpret_cast<char*>(kRtpMsgWithInvalidLength),
    158       sizeof(kRtpMsgWithInvalidLength),
    159       &start_pos, &rtp_length));
    160   EXPECT_EQ(INT_MAX, start_pos);
    161   EXPECT_EQ(INT_MAX, rtp_length);
    162 
    163   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    164       reinterpret_cast<char*>(kRtpMsgWithInvalidExtnLength),
    165       sizeof(kRtpMsgWithInvalidExtnLength),
    166       &start_pos, &rtp_length));
    167   EXPECT_EQ(INT_MAX, start_pos);
    168   EXPECT_EQ(INT_MAX, rtp_length);
    169 }
    170 
    171 // Verify invalid TURN send indication messages. Messages are proper STUN
    172 // messages with incorrect values in attributes.
    173 TEST(P2PSocketHostTest, TestInvalidTurnSendIndicationMessages) {
    174   // Initializing out params to very large value.
    175   int start_pos = INT_MAX, rtp_length = INT_MAX;
    176   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    177       reinterpret_cast<char*>(kTurnSendIndicationMsgWithNoAttributes),
    178       sizeof(kTurnSendIndicationMsgWithNoAttributes),
    179       &start_pos, &rtp_length));
    180   EXPECT_EQ(INT_MAX, start_pos);
    181   EXPECT_EQ(INT_MAX, rtp_length);
    182 
    183   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    184       reinterpret_cast<char*>(kTurnSendIndicationMsgWithInvalidLength),
    185       sizeof(kTurnSendIndicationMsgWithInvalidLength),
    186       &start_pos, &rtp_length));
    187   EXPECT_EQ(INT_MAX, start_pos);
    188   EXPECT_EQ(INT_MAX, rtp_length);
    189 
    190   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    191       reinterpret_cast<char*>(kTurnSendIndicatinMsgWithNoDataAttribute),
    192       sizeof(kTurnSendIndicatinMsgWithNoDataAttribute),
    193       &start_pos, &rtp_length));
    194   EXPECT_EQ(INT_MAX, start_pos);
    195   EXPECT_EQ(INT_MAX, rtp_length);
    196 }
    197 
    198 // This test verifies incorrectly formed TURN channel messages.
    199 TEST(P2PSocketHostTest, TestInvalidTurnChannelMessages) {
    200   int start_pos = INT_MAX, rtp_length = INT_MAX;
    201   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    202       reinterpret_cast<char*>(kTurnChannelMsgNoRtpPacket),
    203       sizeof(kTurnChannelMsgNoRtpPacket),
    204       &start_pos, &rtp_length));
    205   EXPECT_EQ(INT_MAX, start_pos);
    206   EXPECT_EQ(INT_MAX, rtp_length);
    207 
    208   EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    209       reinterpret_cast<char*>(kTurnChannelMsgWithZeroLength),
    210       sizeof(kTurnChannelMsgWithZeroLength),
    211       &start_pos, &rtp_length));
    212   EXPECT_EQ(INT_MAX, start_pos);
    213   EXPECT_EQ(INT_MAX, rtp_length);
    214 }
    215 
    216 // This test verifies parsing of a valid RTP packet which has 2byte header
    217 // extension instead of a 1 byte header extension.
    218 TEST(P2PSocketHostTest, TestValid2ByteExtnHdrRtpMessage) {
    219   int start_pos = INT_MAX, rtp_length = INT_MAX;
    220   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    221       reinterpret_cast<char*>(kRtpMsgWith2ByteExtnHeader),
    222       sizeof(kRtpMsgWith2ByteExtnHeader),
    223       &start_pos, &rtp_length));
    224   EXPECT_EQ(20, rtp_length);
    225   EXPECT_EQ(0, start_pos);
    226 }
    227 
    228 // This test verifies parsing of a valid RTP packet which has 1 byte header
    229 // AbsSendTime extension in it.
    230 TEST(P2PSocketHostTest, TestValidRtpPacketWithAbsSendTimeExtension) {
    231   int start_pos = INT_MAX, rtp_length = INT_MAX;
    232   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    233       reinterpret_cast<char*>(kRtpMsgWithAbsSendTimeExtension),
    234       sizeof(kRtpMsgWithAbsSendTimeExtension),
    235       &start_pos, &rtp_length));
    236   EXPECT_EQ(24, rtp_length);
    237   EXPECT_EQ(0, start_pos);
    238 }
    239 
    240 // This test verifies parsing of a valid TURN Send Indication messages.
    241 TEST(P2PSocketHostTest, TestValidTurnSendIndicationMessages) {
    242   int start_pos = INT_MAX, rtp_length = INT_MAX;
    243   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    244       reinterpret_cast<char*>(kTurnSendIndicationMsgWithoutRtpExtension),
    245       sizeof(kTurnSendIndicationMsgWithoutRtpExtension),
    246       &start_pos, &rtp_length));
    247   EXPECT_EQ(12, rtp_length);
    248   EXPECT_EQ(32, start_pos);
    249 
    250   start_pos = INT_MAX, rtp_length = INT_MAX;
    251   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    252       reinterpret_cast<char*>(kTurnSendIndicationMsgWithAbsSendTimeExtension),
    253       sizeof(kTurnSendIndicationMsgWithAbsSendTimeExtension),
    254       &start_pos, &rtp_length));
    255   EXPECT_EQ(24, rtp_length);
    256   EXPECT_EQ(32, start_pos);
    257 }
    258 
    259 // This test verifies parsing of valid TURN Channel Messages.
    260 TEST(P2PSocketHostTest, TestValidTurnChannelMessages) {
    261   int start_pos = -1, rtp_length = -1;
    262   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    263       reinterpret_cast<char*>(kTurnChannelMsgWithRtpPacket),
    264       sizeof(kTurnChannelMsgWithRtpPacket), &start_pos, &rtp_length));
    265   EXPECT_EQ(12, rtp_length);
    266   EXPECT_EQ(4, start_pos);
    267 
    268   start_pos = -1, rtp_length = -1;
    269   EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
    270       reinterpret_cast<char*>(kTurnChannelMsgWithAbsSendTimeExtension),
    271       sizeof(kTurnChannelMsgWithAbsSendTimeExtension),
    272       &start_pos, &rtp_length));
    273   EXPECT_EQ(20, rtp_length);
    274   EXPECT_EQ(4, start_pos);
    275 }
    276 
    277 // Verify handling of a 2 byte extension header RTP messsage. Currently we don't
    278 // handle this kind of message.
    279 TEST(P2PSocketHostTest, TestUpdateAbsSendTimeExtensionIn2ByteHeaderExtn) {
    280   EXPECT_FALSE(packet_processing_helpers::UpdateRtpAbsSendTimeExtn(
    281     reinterpret_cast<char*>(kRtpMsgWith2ByteExtnHeader),
    282     sizeof(kRtpMsgWith2ByteExtnHeader), 3, 0));
    283 }
    284 
    285 // Verify finding an extension ID in the TURN send indication message.
    286 TEST(P2PSocketHostTest, TestUpdateAbsSendTimeExtensionInTurnSendIndication) {
    287   EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtn(
    288       reinterpret_cast<char*>(kTurnSendIndicationMsgWithoutRtpExtension),
    289       sizeof(kTurnSendIndicationMsgWithoutRtpExtension), 3, 0));
    290 
    291   EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtn(
    292       reinterpret_cast<char*>(kTurnSendIndicationMsgWithAbsSendTimeExtension),
    293       sizeof(kTurnSendIndicationMsgWithAbsSendTimeExtension), 3, 0));
    294 }
    295 
    296 // Test without any packet options variables set. This method should return
    297 // without HMAC value in the packet.
    298 TEST(P2PSocketHostTest, TestApplyPacketOptionsWithDefaultValues) {
    299   unsigned char fake_tag[4] = { 0xba, 0xdd, 0xba, 0xdd };
    300   talk_base::PacketOptions options;
    301   std::vector<char> rtp_packet;
    302   rtp_packet.resize(sizeof(kRtpMsgWithAbsSendTimeExtension) + 4);  // tag length
    303   memcpy(&rtp_packet[0], kRtpMsgWithAbsSendTimeExtension,
    304          sizeof(kRtpMsgWithAbsSendTimeExtension));
    305   memcpy(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)], fake_tag, 4);
    306   EXPECT_TRUE(
    307       packet_processing_helpers::ApplyPacketOptions(
    308       &rtp_packet[0], rtp_packet.size(), options, 0));
    309   // Making sure we have't updated the HMAC.
    310   EXPECT_EQ(0, memcmp(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)],
    311                       fake_tag, 4));
    312 
    313   // Verify AbsouluteSendTime extension field is not modified.
    314   EXPECT_EQ(0, memcmp(&rtp_packet[kAstIndexInRtpMsg],
    315                       kTestAstValue, sizeof(kTestAstValue)));
    316 }
    317 
    318 // Veirfy HMAC is updated when packet option parameters are set.
    319 TEST(P2PSocketHostTest, TestApplyPacketOptionsWithAuthParams) {
    320   talk_base::PacketOptions options;
    321   options.packet_time_params.srtp_auth_key.resize(20);
    322   options.packet_time_params.srtp_auth_key.assign(
    323       kTestKey, kTestKey + sizeof(kTestKey));
    324   options.packet_time_params.srtp_auth_tag_len = 4;
    325 
    326   std::vector<char> rtp_packet;
    327   rtp_packet.resize(sizeof(kRtpMsgWithAbsSendTimeExtension) + 4);  // tag length
    328   memcpy(&rtp_packet[0], kRtpMsgWithAbsSendTimeExtension,
    329          sizeof(kRtpMsgWithAbsSendTimeExtension));
    330   memcpy(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)], kFakeTag, 4);
    331   EXPECT_TRUE(packet_processing_helpers::ApplyPacketOptions(
    332                   &rtp_packet[0], rtp_packet.size(), options, 0));
    333   // HMAC should be different from fake_tag.
    334   EXPECT_NE(0, memcmp(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)],
    335                       kFakeTag, sizeof(kFakeTag)));
    336 
    337    // Verify AbsouluteSendTime extension field is not modified.
    338   EXPECT_EQ(0, memcmp(&rtp_packet[kAstIndexInRtpMsg],
    339                       kTestAstValue, sizeof(kTestAstValue)));
    340 }
    341 
    342 // Verify finding an extension ID in a raw rtp message.
    343 TEST(P2PSocketHostTest, TestUpdateAbsSendTimeExtensionInRtpPacket) {
    344   EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtn(
    345       reinterpret_cast<char*>(kRtpMsgWithAbsSendTimeExtension),
    346       sizeof(kRtpMsgWithAbsSendTimeExtension), 3, 0));
    347 }
    348 
    349 // Verify we update both AbsSendTime extension header and HMAC.
    350 TEST(P2PSocketHostTest, TestApplyPacketOptionsWithAuthParamsAndAbsSendTime) {
    351   talk_base::PacketOptions options;
    352   options.packet_time_params.srtp_auth_key.resize(20);
    353   options.packet_time_params.srtp_auth_key.assign(
    354       kTestKey, kTestKey + sizeof(kTestKey));
    355   options.packet_time_params.srtp_auth_tag_len = 4;
    356   options.packet_time_params.rtp_sendtime_extension_id = 3;
    357   // 3 is also present in the test message.
    358 
    359   std::vector<char> rtp_packet;
    360   rtp_packet.resize(sizeof(kRtpMsgWithAbsSendTimeExtension) + 4);  // tag length
    361   memcpy(&rtp_packet[0], kRtpMsgWithAbsSendTimeExtension,
    362          sizeof(kRtpMsgWithAbsSendTimeExtension));
    363   memcpy(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)], kFakeTag, 4);
    364   EXPECT_TRUE(packet_processing_helpers::ApplyPacketOptions(
    365                   &rtp_packet[0], rtp_packet.size(), options, 0xccbbaa));
    366   // HMAC should be different from fake_tag.
    367   EXPECT_NE(0, memcmp(&rtp_packet[sizeof(kRtpMsgWithAbsSendTimeExtension)],
    368                       kFakeTag, sizeof(kFakeTag)));
    369 
    370   // ApplyPackets should have the new timestamp passed as input.
    371   unsigned char timestamp_array[3] = { 0xcc, 0xbb, 0xaa };
    372   EXPECT_EQ(0, memcmp(&rtp_packet[kAstIndexInRtpMsg],
    373                       timestamp_array, sizeof(timestamp_array)));
    374 }
    375 
    376 }  // namespace content
    377