You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
15 KiB

  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package otr
  5. import (
  6. "bufio"
  7. "bytes"
  8. "crypto/rand"
  9. "encoding/hex"
  10. "math/big"
  11. "os"
  12. "os/exec"
  13. "testing"
  14. )
  15. var isQueryTests = []struct {
  16. msg string
  17. expectedVersion int
  18. }{
  19. {"foo", 0},
  20. {"?OtR", 0},
  21. {"?OtR?", 0},
  22. {"?OTR?", 0},
  23. {"?OTRv?", 0},
  24. {"?OTRv1?", 0},
  25. {"?OTR?v1?", 0},
  26. {"?OTR?v?", 0},
  27. {"?OTR?v2?", 2},
  28. {"?OTRv2?", 2},
  29. {"?OTRv23?", 2},
  30. {"?OTRv23 ?", 0},
  31. }
  32. func TestIsQuery(t *testing.T) {
  33. for i, test := range isQueryTests {
  34. version := isQuery([]byte(test.msg))
  35. if version != test.expectedVersion {
  36. t.Errorf("#%d: got %d, want %d", i, version, test.expectedVersion)
  37. }
  38. }
  39. }
  40. var alicePrivateKeyHex = "000000000080c81c2cb2eb729b7e6fd48e975a932c638b3a9055478583afa46755683e30102447f6da2d8bec9f386bbb5da6403b0040fee8650b6ab2d7f32c55ab017ae9b6aec8c324ab5844784e9a80e194830d548fb7f09a0410df2c4d5c8bc2b3e9ad484e65412be689cf0834694e0839fb2954021521ffdffb8f5c32c14dbf2020b3ce7500000014da4591d58def96de61aea7b04a8405fe1609308d000000808ddd5cb0b9d66956e3dea5a915d9aba9d8a6e7053b74dadb2fc52f9fe4e5bcc487d2305485ed95fed026ad93f06ebb8c9e8baf693b7887132c7ffdd3b0f72f4002ff4ed56583ca7c54458f8c068ca3e8a4dfa309d1dd5d34e2a4b68e6f4338835e5e0fb4317c9e4c7e4806dafda3ef459cd563775a586dd91b1319f72621bf3f00000080b8147e74d8c45e6318c37731b8b33b984a795b3653c2cd1d65cc99efe097cb7eb2fa49569bab5aab6e8a1c261a27d0f7840a5e80b317e6683042b59b6dceca2879c6ffc877a465be690c15e4a42f9a7588e79b10faac11b1ce3741fcef7aba8ce05327a2c16d279ee1b3d77eb783fb10e3356caa25635331e26dd42b8396c4d00000001420bec691fea37ecea58a5c717142f0b804452f57"
  41. var aliceFingerprintHex = "0bb01c360424522e94ee9c346ce877a1a4288b2f"
  42. var bobPrivateKeyHex = "000000000080a5138eb3d3eb9c1d85716faecadb718f87d31aaed1157671d7fee7e488f95e8e0ba60ad449ec732710a7dec5190f7182af2e2f98312d98497221dff160fd68033dd4f3a33b7c078d0d9f66e26847e76ca7447d4bab35486045090572863d9e4454777f24d6706f63e02548dfec2d0a620af37bbc1d24f884708a212c343b480d00000014e9c58f0ea21a5e4dfd9f44b6a9f7f6a9961a8fa9000000803c4d111aebd62d3c50c2889d420a32cdf1e98b70affcc1fcf44d59cca2eb019f6b774ef88153fb9b9615441a5fe25ea2d11b74ce922ca0232bd81b3c0fcac2a95b20cb6e6c0c5c1ace2e26f65dc43c751af0edbb10d669890e8ab6beea91410b8b2187af1a8347627a06ecea7e0f772c28aae9461301e83884860c9b656c722f0000008065af8625a555ea0e008cd04743671a3cda21162e83af045725db2eb2bb52712708dc0cc1a84c08b3649b88a966974bde27d8612c2861792ec9f08786a246fcadd6d8d3a81a32287745f309238f47618c2bd7612cb8b02d940571e0f30b96420bcd462ff542901b46109b1e5ad6423744448d20a57818a8cbb1647d0fea3b664e0000001440f9f2eb554cb00d45a5826b54bfa419b6980e48"
  43. func TestKeySerialization(t *testing.T) {
  44. var priv PrivateKey
  45. alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex)
  46. rest, ok := priv.Parse(alicePrivateKey)
  47. if !ok {
  48. t.Error("failed to parse private key")
  49. }
  50. if len(rest) > 0 {
  51. t.Error("data remaining after parsing private key")
  52. }
  53. out := priv.Serialize(nil)
  54. if !bytes.Equal(alicePrivateKey, out) {
  55. t.Errorf("serialization (%x) is not equal to original (%x)", out, alicePrivateKey)
  56. }
  57. aliceFingerprint, _ := hex.DecodeString(aliceFingerprintHex)
  58. fingerprint := priv.PublicKey.Fingerprint()
  59. if !bytes.Equal(aliceFingerprint, fingerprint) {
  60. t.Errorf("fingerprint (%x) is not equal to expected value (%x)", fingerprint, aliceFingerprint)
  61. }
  62. }
  63. const libOTRPrivateKey = `(privkeys
  64. (account
  65. (name "foo@example.com")
  66. (protocol prpl-jabber)
  67. (private-key
  68. (dsa
  69. (p #00FC07ABCF0DC916AFF6E9AE47BEF60C7AB9B4D6B2469E436630E36F8A489BE812486A09F30B71224508654940A835301ACC525A4FF133FC152CC53DCC59D65C30A54F1993FE13FE63E5823D4C746DB21B90F9B9C00B49EC7404AB1D929BA7FBA12F2E45C6E0A651689750E8528AB8C031D3561FECEE72EBB4A090D450A9B7A857#)
  70. (q #00997BD266EF7B1F60A5C23F3A741F2AEFD07A2081#)
  71. (g #535E360E8A95EBA46A4F7DE50AD6E9B2A6DB785A66B64EB9F20338D2A3E8FB0E94725848F1AA6CC567CB83A1CC517EC806F2E92EAE71457E80B2210A189B91250779434B41FC8A8873F6DB94BEA7D177F5D59E7E114EE10A49CFD9CEF88AE43387023B672927BA74B04EB6BBB5E57597766A2F9CE3857D7ACE3E1E3BC1FC6F26#)
  72. (y #0AC8670AD767D7A8D9D14CC1AC6744CD7D76F993B77FFD9E39DF01E5A6536EF65E775FCEF2A983E2A19BD6415500F6979715D9FD1257E1FE2B6F5E1E74B333079E7C880D39868462A93454B41877BE62E5EF0A041C2EE9C9E76BD1E12AE25D9628DECB097025DD625EF49C3258A1A3C0FF501E3DC673B76D7BABF349009B6ECF#)
  73. (x #14D0345A3562C480A039E3C72764F72D79043216#)
  74. )
  75. )
  76. )
  77. )`
  78. func TestParseLibOTRPrivateKey(t *testing.T) {
  79. var priv PrivateKey
  80. if !priv.Import([]byte(libOTRPrivateKey)) {
  81. t.Fatalf("Failed to import sample private key")
  82. }
  83. }
  84. func TestSignVerify(t *testing.T) {
  85. var priv PrivateKey
  86. alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex)
  87. _, ok := priv.Parse(alicePrivateKey)
  88. if !ok {
  89. t.Error("failed to parse private key")
  90. }
  91. var msg [32]byte
  92. rand.Reader.Read(msg[:])
  93. sig := priv.Sign(rand.Reader, msg[:])
  94. rest, ok := priv.PublicKey.Verify(msg[:], sig)
  95. if !ok {
  96. t.Errorf("signature (%x) of %x failed to verify", sig, msg[:])
  97. } else if len(rest) > 0 {
  98. t.Error("signature data remains after verification")
  99. }
  100. sig[10] ^= 80
  101. _, ok = priv.PublicKey.Verify(msg[:], sig)
  102. if ok {
  103. t.Errorf("corrupted signature (%x) of %x verified", sig, msg[:])
  104. }
  105. }
  106. func setupConversation(t *testing.T) (alice, bob *Conversation) {
  107. alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex)
  108. bobPrivateKey, _ := hex.DecodeString(bobPrivateKeyHex)
  109. alice, bob = new(Conversation), new(Conversation)
  110. alice.PrivateKey = new(PrivateKey)
  111. bob.PrivateKey = new(PrivateKey)
  112. alice.PrivateKey.Parse(alicePrivateKey)
  113. bob.PrivateKey.Parse(bobPrivateKey)
  114. alice.FragmentSize = 100
  115. bob.FragmentSize = 100
  116. if alice.IsEncrypted() {
  117. t.Error("Alice believes that the conversation is secure before we've started")
  118. }
  119. if bob.IsEncrypted() {
  120. t.Error("Bob believes that the conversation is secure before we've started")
  121. }
  122. performHandshake(t, alice, bob)
  123. return alice, bob
  124. }
  125. func performHandshake(t *testing.T, alice, bob *Conversation) {
  126. var alicesMessage, bobsMessage [][]byte
  127. var out []byte
  128. var aliceChange, bobChange SecurityChange
  129. var err error
  130. alicesMessage = append(alicesMessage, []byte(QueryMessage))
  131. for round := 0; len(alicesMessage) > 0 || len(bobsMessage) > 0; round++ {
  132. bobsMessage = nil
  133. for i, msg := range alicesMessage {
  134. out, _, bobChange, bobsMessage, err = bob.Receive(msg)
  135. if len(out) > 0 {
  136. t.Errorf("Bob generated output during key exchange, round %d, message %d", round, i)
  137. }
  138. if err != nil {
  139. t.Fatalf("Bob returned an error, round %d, message %d (%x): %s", round, i, msg, err)
  140. }
  141. if len(bobsMessage) > 0 && i != len(alicesMessage)-1 {
  142. t.Errorf("Bob produced output while processing a fragment, round %d, message %d", round, i)
  143. }
  144. }
  145. alicesMessage = nil
  146. for i, msg := range bobsMessage {
  147. out, _, aliceChange, alicesMessage, err = alice.Receive(msg)
  148. if len(out) > 0 {
  149. t.Errorf("Alice generated output during key exchange, round %d, message %d", round, i)
  150. }
  151. if err != nil {
  152. t.Fatalf("Alice returned an error, round %d, message %d (%x): %s", round, i, msg, err)
  153. }
  154. if len(alicesMessage) > 0 && i != len(bobsMessage)-1 {
  155. t.Errorf("Alice produced output while processing a fragment, round %d, message %d", round, i)
  156. }
  157. }
  158. }
  159. if aliceChange != NewKeys {
  160. t.Errorf("Alice terminated without signaling new keys")
  161. }
  162. if bobChange != NewKeys {
  163. t.Errorf("Bob terminated without signaling new keys")
  164. }
  165. if !bytes.Equal(alice.SSID[:], bob.SSID[:]) {
  166. t.Errorf("Session identifiers don't match. Alice has %x, Bob has %x", alice.SSID[:], bob.SSID[:])
  167. }
  168. if !alice.IsEncrypted() {
  169. t.Error("Alice doesn't believe that the conversation is secure")
  170. }
  171. if !bob.IsEncrypted() {
  172. t.Error("Bob doesn't believe that the conversation is secure")
  173. }
  174. }
  175. const (
  176. firstRoundTrip = iota
  177. subsequentRoundTrip
  178. noMACKeyCheck
  179. )
  180. func roundTrip(t *testing.T, alice, bob *Conversation, message []byte, macKeyCheck int) {
  181. alicesMessage, err := alice.Send(message)
  182. if err != nil {
  183. t.Errorf("Error from Alice sending message: %s", err)
  184. }
  185. if len(alice.oldMACs) != 0 {
  186. t.Errorf("Alice has not revealed all MAC keys")
  187. }
  188. for i, msg := range alicesMessage {
  189. out, encrypted, _, _, err := bob.Receive(msg)
  190. if err != nil {
  191. t.Errorf("Error generated while processing test message: %s", err.Error())
  192. }
  193. if len(out) > 0 {
  194. if i != len(alicesMessage)-1 {
  195. t.Fatal("Bob produced a message while processing a fragment of Alice's")
  196. }
  197. if !encrypted {
  198. t.Errorf("Message was not marked as encrypted")
  199. }
  200. if !bytes.Equal(out, message) {
  201. t.Errorf("Message corrupted: got %x, want %x", out, message)
  202. }
  203. }
  204. }
  205. switch macKeyCheck {
  206. case firstRoundTrip:
  207. if len(bob.oldMACs) != 0 {
  208. t.Errorf("Bob should not have MAC keys to reveal")
  209. }
  210. case subsequentRoundTrip:
  211. if len(bob.oldMACs) != 40 {
  212. t.Errorf("Bob has %d bytes of MAC keys to reveal, but should have 40", len(bob.oldMACs))
  213. }
  214. }
  215. bobsMessage, err := bob.Send(message)
  216. if err != nil {
  217. t.Errorf("Error from Bob sending message: %s", err)
  218. }
  219. if len(bob.oldMACs) != 0 {
  220. t.Errorf("Bob has not revealed all MAC keys")
  221. }
  222. for i, msg := range bobsMessage {
  223. out, encrypted, _, _, err := alice.Receive(msg)
  224. if err != nil {
  225. t.Errorf("Error generated while processing test message: %s", err.Error())
  226. }
  227. if len(out) > 0 {
  228. if i != len(bobsMessage)-1 {
  229. t.Fatal("Alice produced a message while processing a fragment of Bob's")
  230. }
  231. if !encrypted {
  232. t.Errorf("Message was not marked as encrypted")
  233. }
  234. if !bytes.Equal(out, message) {
  235. t.Errorf("Message corrupted: got %x, want %x", out, message)
  236. }
  237. }
  238. }
  239. switch macKeyCheck {
  240. case firstRoundTrip:
  241. if len(alice.oldMACs) != 20 {
  242. t.Errorf("Alice has %d bytes of MAC keys to reveal, but should have 20", len(alice.oldMACs))
  243. }
  244. case subsequentRoundTrip:
  245. if len(alice.oldMACs) != 40 {
  246. t.Errorf("Alice has %d bytes of MAC keys to reveal, but should have 40", len(alice.oldMACs))
  247. }
  248. }
  249. }
  250. func TestConversation(t *testing.T) {
  251. alice, bob := setupConversation(t)
  252. var testMessages = [][]byte{
  253. []byte("hello"), []byte("bye"),
  254. }
  255. roundTripType := firstRoundTrip
  256. for _, testMessage := range testMessages {
  257. roundTrip(t, alice, bob, testMessage, roundTripType)
  258. roundTripType = subsequentRoundTrip
  259. }
  260. }
  261. func TestGoodSMP(t *testing.T) {
  262. var alice, bob Conversation
  263. alice.smp.secret = new(big.Int).SetInt64(42)
  264. bob.smp.secret = alice.smp.secret
  265. var alicesMessages, bobsMessages []tlv
  266. var aliceComplete, bobComplete bool
  267. var err error
  268. var out tlv
  269. alicesMessages = alice.startSMP("")
  270. for round := 0; len(alicesMessages) > 0 || len(bobsMessages) > 0; round++ {
  271. bobsMessages = bobsMessages[:0]
  272. for i, msg := range alicesMessages {
  273. out, bobComplete, err = bob.processSMP(msg)
  274. if err != nil {
  275. t.Errorf("Error from Bob in round %d: %s", round, err)
  276. }
  277. if bobComplete && i != len(alicesMessages)-1 {
  278. t.Errorf("Bob returned a completed signal before processing all of Alice's messages in round %d", round)
  279. }
  280. if out.typ != 0 {
  281. bobsMessages = append(bobsMessages, out)
  282. }
  283. }
  284. alicesMessages = alicesMessages[:0]
  285. for i, msg := range bobsMessages {
  286. out, aliceComplete, err = alice.processSMP(msg)
  287. if err != nil {
  288. t.Errorf("Error from Alice in round %d: %s", round, err)
  289. }
  290. if aliceComplete && i != len(bobsMessages)-1 {
  291. t.Errorf("Alice returned a completed signal before processing all of Bob's messages in round %d", round)
  292. }
  293. if out.typ != 0 {
  294. alicesMessages = append(alicesMessages, out)
  295. }
  296. }
  297. }
  298. if !aliceComplete || !bobComplete {
  299. t.Errorf("SMP completed without both sides reporting success: alice: %v, bob: %v\n", aliceComplete, bobComplete)
  300. }
  301. }
  302. func TestBadSMP(t *testing.T) {
  303. var alice, bob Conversation
  304. alice.smp.secret = new(big.Int).SetInt64(42)
  305. bob.smp.secret = new(big.Int).SetInt64(43)
  306. var alicesMessages, bobsMessages []tlv
  307. alicesMessages = alice.startSMP("")
  308. for round := 0; len(alicesMessages) > 0 || len(bobsMessages) > 0; round++ {
  309. bobsMessages = bobsMessages[:0]
  310. for _, msg := range alicesMessages {
  311. out, complete, _ := bob.processSMP(msg)
  312. if complete {
  313. t.Errorf("Bob signaled completion in round %d", round)
  314. }
  315. if out.typ != 0 {
  316. bobsMessages = append(bobsMessages, out)
  317. }
  318. }
  319. alicesMessages = alicesMessages[:0]
  320. for _, msg := range bobsMessages {
  321. out, complete, _ := alice.processSMP(msg)
  322. if complete {
  323. t.Errorf("Alice signaled completion in round %d", round)
  324. }
  325. if out.typ != 0 {
  326. alicesMessages = append(alicesMessages, out)
  327. }
  328. }
  329. }
  330. }
  331. func TestRehandshaking(t *testing.T) {
  332. alice, bob := setupConversation(t)
  333. roundTrip(t, alice, bob, []byte("test"), firstRoundTrip)
  334. roundTrip(t, alice, bob, []byte("test 2"), subsequentRoundTrip)
  335. roundTrip(t, alice, bob, []byte("test 3"), subsequentRoundTrip)
  336. roundTrip(t, alice, bob, []byte("test 4"), subsequentRoundTrip)
  337. roundTrip(t, alice, bob, []byte("test 5"), subsequentRoundTrip)
  338. roundTrip(t, alice, bob, []byte("test 6"), subsequentRoundTrip)
  339. roundTrip(t, alice, bob, []byte("test 7"), subsequentRoundTrip)
  340. roundTrip(t, alice, bob, []byte("test 8"), subsequentRoundTrip)
  341. performHandshake(t, alice, bob)
  342. roundTrip(t, alice, bob, []byte("test"), noMACKeyCheck)
  343. roundTrip(t, alice, bob, []byte("test 2"), noMACKeyCheck)
  344. }
  345. func TestAgainstLibOTR(t *testing.T) {
  346. // This test requires otr.c.test to be built as /tmp/a.out.
  347. // If enabled, this tests runs forever performing OTR handshakes in a
  348. // loop.
  349. return
  350. alicePrivateKey, _ := hex.DecodeString(alicePrivateKeyHex)
  351. var alice Conversation
  352. alice.PrivateKey = new(PrivateKey)
  353. alice.PrivateKey.Parse(alicePrivateKey)
  354. cmd := exec.Command("/tmp/a.out")
  355. cmd.Stderr = os.Stderr
  356. out, err := cmd.StdinPipe()
  357. if err != nil {
  358. t.Fatal(err)
  359. }
  360. defer out.Close()
  361. stdout, err := cmd.StdoutPipe()
  362. if err != nil {
  363. t.Fatal(err)
  364. }
  365. in := bufio.NewReader(stdout)
  366. if err := cmd.Start(); err != nil {
  367. t.Fatal(err)
  368. }
  369. out.Write([]byte(QueryMessage))
  370. out.Write([]byte("\n"))
  371. var expectedText = []byte("test message")
  372. for {
  373. line, isPrefix, err := in.ReadLine()
  374. if isPrefix {
  375. t.Fatal("line from subprocess too long")
  376. }
  377. if err != nil {
  378. t.Fatal(err)
  379. }
  380. text, encrypted, change, alicesMessage, err := alice.Receive(line)
  381. if err != nil {
  382. t.Fatal(err)
  383. }
  384. for _, msg := range alicesMessage {
  385. out.Write(msg)
  386. out.Write([]byte("\n"))
  387. }
  388. if change == NewKeys {
  389. alicesMessage, err := alice.Send([]byte("Go -> libotr test message"))
  390. if err != nil {
  391. t.Fatalf("error sending message: %s", err.Error())
  392. } else {
  393. for _, msg := range alicesMessage {
  394. out.Write(msg)
  395. out.Write([]byte("\n"))
  396. }
  397. }
  398. }
  399. if len(text) > 0 {
  400. if !bytes.Equal(text, expectedText) {
  401. t.Fatalf("expected %x, but got %x", expectedText, text)
  402. }
  403. if !encrypted {
  404. t.Fatal("message wasn't encrypted")
  405. }
  406. }
  407. }
  408. }