1package stun 2 3import ( 4 "net" 5 "testing" 6) 7 8func TestRFC5769(t *testing.T) { 9 // Test Vectors for Session Traversal Utilities for NAT (STUN) 10 // see https://tools.ietf.org/html/rfc5769 11 t.Run("Request", func(t *testing.T) { 12 m := &Message{ 13 Raw: []byte("\x00\x01\x00\x58" + 14 "\x21\x12\xa4\x42" + 15 "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + 16 "\x80\x22\x00\x10" + 17 "STUN test client" + 18 "\x00\x24\x00\x04" + 19 "\x6e\x00\x01\xff" + 20 "\x80\x29\x00\x08" + 21 "\x93\x2f\xf9\xb1\x51\x26\x3b\x36" + 22 "\x00\x06\x00\x09" + 23 "\x65\x76\x74\x6a\x3a\x68\x36\x76\x59\x20\x20\x20" + 24 "\x00\x08\x00\x14" + 25 "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5" + 26 "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2" + 27 "\x80\x28\x00\x04" + 28 "\xe5\x7a\x3b\xcf", 29 ), 30 } 31 if err := m.Decode(); err != nil { 32 t.Error(err) 33 } 34 software := new(Software) 35 if err := software.GetFrom(m); err != nil { 36 t.Error(err) 37 } 38 if software.String() != "STUN test client" { 39 t.Error("bad software: ", software) 40 } 41 if err := Fingerprint.Check(m); err != nil { 42 t.Error("check failed: ", err) 43 } 44 t.Run("Long-Term credentials", func(t *testing.T) { 45 m := &Message{ 46 Raw: []byte("\x00\x01\x00\x60" + 47 "\x21\x12\xa4\x42" + 48 "\x78\xad\x34\x33\xc6\xad\x72\xc0\x29\xda\x41\x2e" + 49 "\x00\x06\x00\x12" + 50 "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83" + 51 "\xe3\x82\xaf\xe3\x82\xb9\x00\x00" + 52 "\x00\x15\x00\x1c" + 53 "\x66\x2f\x2f\x34\x39\x39\x6b\x39\x35\x34\x64\x36" + 54 "\x4f\x4c\x33\x34\x6f\x4c\x39\x46\x53\x54\x76\x79" + 55 "\x36\x34\x73\x41" + 56 "\x00\x14\x00\x0b" + 57 "\x65\x78\x61\x6d\x70\x6c\x65\x2e\x6f\x72\x67\x00" + 58 "\x00\x08\x00\x14" + 59 "\xf6\x70\x24\x65\x6d\xd6\x4a\x3e\x02\xb8\xe0\x71" + 60 "\x2e\x85\xc9\xa2\x8c\xa8\x96\x66", 61 ), 62 } 63 if err := m.Decode(); err != nil { 64 t.Error(err) 65 } 66 u := new(Username) 67 if err := u.GetFrom(m); err != nil { 68 t.Error(err) 69 } 70 expectedUsername := "\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9" 71 if u.String() != expectedUsername { 72 t.Errorf("username: %q (got) != %q (exp)", u, expectedUsername) 73 } 74 n := new(Nonce) 75 if err := n.GetFrom(m); err != nil { 76 t.Error(err) 77 } 78 if n.String() != "f//499k954d6OL34oL9FSTvy64sA" { 79 t.Error("bad nonce") 80 } 81 r := new(Realm) 82 if err := r.GetFrom(m); err != nil { 83 t.Error(err) 84 } 85 if r.String() != "example.org" { 86 t.Error("bad realm") 87 } 88 // checking HMAC 89 i := NewLongTermIntegrity( 90 "\u30DE\u30C8\u30EA\u30C3\u30AF\u30B9", 91 "example.org", 92 "TheMatrIX", 93 ) 94 if err := i.Check(m); err != nil { 95 t.Error(err) 96 } 97 }) 98 }) 99 t.Run("Response", func(t *testing.T) { 100 t.Run("IPv4", func(t *testing.T) { 101 m := &Message{ 102 Raw: []byte("\x01\x01\x00\x3c" + 103 "\x21\x12\xa4\x42" + 104 "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + 105 "\x80\x22\x00\x0b" + 106 "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" + 107 "\x00\x20\x00\x08" + 108 "\x00\x01\xa1\x47\xe1\x12\xa6\x43" + 109 "\x00\x08\x00\x14" + 110 "\x2b\x91\xf5\x99\xfd\x9e\x90\xc3\x8c\x74\x89\xf9" + 111 "\x2a\xf9\xba\x53\xf0\x6b\xe7\xd7" + 112 "\x80\x28\x00\x04" + 113 "\xc0\x7d\x4c\x96", 114 ), 115 } 116 if err := m.Decode(); err != nil { 117 t.Error(err) 118 } 119 software := new(Software) 120 if err := software.GetFrom(m); err != nil { 121 t.Error(err) 122 } 123 if software.String() != "test vector" { 124 t.Error("bad software: ", software) 125 } 126 if err := Fingerprint.Check(m); err != nil { 127 t.Error("Check failed: ", err) 128 } 129 addr := new(XORMappedAddress) 130 if err := addr.GetFrom(m); err != nil { 131 t.Error(err) 132 } 133 if !addr.IP.Equal(net.ParseIP("192.0.2.1")) { 134 t.Error("bad IP") 135 } 136 if addr.Port != 32853 { 137 t.Error("bad Port") 138 } 139 if err := Fingerprint.Check(m); err != nil { 140 t.Error("check failed: ", err) 141 } 142 }) 143 t.Run("IPv6", func(t *testing.T) { 144 m := &Message{ 145 Raw: []byte("\x01\x01\x00\x48" + 146 "\x21\x12\xa4\x42" + 147 "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" + 148 "\x80\x22\x00\x0b" + 149 "\x74\x65\x73\x74\x20\x76\x65\x63\x74\x6f\x72\x20" + 150 "\x00\x20\x00\x14" + 151 "\x00\x02\xa1\x47" + 152 "\x01\x13\xa9\xfa\xa5\xd3\xf1\x79" + 153 "\xbc\x25\xf4\xb5\xbe\xd2\xb9\xd9" + 154 "\x00\x08\x00\x14" + 155 "\xa3\x82\x95\x4e\x4b\xe6\x7b\xf1\x17\x84\xc9\x7c" + 156 "\x82\x92\xc2\x75\xbf\xe3\xed\x41" + 157 "\x80\x28\x00\x04" + 158 "\xc8\xfb\x0b\x4c", 159 ), 160 } 161 if err := m.Decode(); err != nil { 162 t.Error(err) 163 } 164 software := new(Software) 165 if err := software.GetFrom(m); err != nil { 166 t.Error(err) 167 } 168 if software.String() != "test vector" { 169 t.Error("bad software: ", software) 170 } 171 if err := Fingerprint.Check(m); err != nil { 172 t.Error("Check failed: ", err) 173 } 174 addr := new(XORMappedAddress) 175 if err := addr.GetFrom(m); err != nil { 176 t.Error(err) 177 } 178 if !addr.IP.Equal(net.ParseIP("2001:db8:1234:5678:11:2233:4455:6677")) { 179 t.Error("bad IP") 180 } 181 if addr.Port != 32853 { 182 t.Error("bad Port") 183 } 184 if err := Fingerprint.Check(m); err != nil { 185 t.Error("check failed: ", err) 186 } 187 }) 188 }) 189} 190