Skip to content

Commit 23fda91

Browse files
committed
Add final support for injecting messages. Also add support for error handling of malformed messages. Final part of coyim#29
1 parent 068530e commit 23fda91

File tree

6 files changed

+51
-18
lines changed

6 files changed

+51
-18
lines changed

data_message_test.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ func Test_processDataMessage_signalsThatMessageIsUnreadableForAGPGConflictError(
251251
}, MessageEventReceivedMessageUnreadable, nil, nil)
252252
}
253253

254-
func Test_processDataMessage_returnsACustomErrorMessageIfOneIsAvailable(t *testing.T) {
254+
func Test_Receive_returnsACustomErrorMessageIfOneIsAvailable(t *testing.T) {
255255
c := newConversation(otrV3{}, rand.Reader)
256256
c.ourKey = bobPrivateKey
257257

@@ -270,8 +270,9 @@ func Test_processDataMessage_returnsACustomErrorMessageIfOneIsAvailable(t *testi
270270
return []byte("white hole happened")
271271
}, nil, nil)
272272

273-
p, _, _ := c.receiveDecoded(msg)
274-
assertDeepEquals(t, string(p), "?OTR Error: nova happened")
273+
c.receiveDecoded(msg)
274+
ts, _ := c.withInjections(nil, nil)
275+
assertDeepEquals(t, string(ts[0]), "?OTR Error: nova happened")
275276
}
276277

277278
func Test_processDataMessage_signalsThatMessageIsMalformedIfSomeOtherErrorHappens(t *testing.T) {
@@ -301,8 +302,9 @@ func Test_processDataMessage_callsErrorMessageHandlerAndReturnsTheResultAsAnOTRE
301302
return []byte("dandelion happened")
302303
}, nil, nil)
303304

304-
plain, _, _ := c.receiveDecoded(msg)
305-
assertDeepEquals(t, string(plain), "?OTR Error: sunflower happened")
305+
c.receiveDecoded(msg)
306+
ts, _ := c.withInjections(nil, nil)
307+
assertDeepEquals(t, string(ts[0]), "?OTR Error: sunflower happened")
306308
}
307309

308310
func Test_processDataMessage_shouldNotRotateKeysWhenDecryptFails(t *testing.T) {

fragmentation_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,27 @@ func Test_receiveFragment_signalsMessageEventIfInstanceTagsDoesNotMatch(t *testi
129129
}, MessageEventReceivedMessageForOtherInstance, nil, nil)
130130
}
131131

132+
func Test_receiveFragment_sendsAnErrorMessageAboutMalformedIfHandlerExists(t *testing.T) {
133+
c := newConversation(otrV3{}, rand.Reader)
134+
c.ourInstanceTag = 0x103
135+
c.theirInstanceTag = 0x0A
136+
137+
existingContext := fragmentationContext{frag: []byte("shouldn't change")}
138+
139+
c.eventHandler = emptyEventHandlerWith(
140+
func() bool { return true },
141+
func(error ErrorCode) []byte {
142+
if error == ErrorCodeMessageMalformed {
143+
return []byte("black happened")
144+
}
145+
return []byte("white happened")
146+
}, nil, nil)
147+
148+
c.receiveFragment(existingContext, []byte("?OTR|0000000A|00000103,00001,00004,one ,"))
149+
ts, _ := c.withInjections(nil, nil)
150+
assertDeepEquals(t, string(ts[0]), "?OTR Error: black happened")
151+
}
152+
132153
func Test_receiveFragment_signalsMalformedMessageIfTheirInstanceTagIsBelowTheLimit(t *testing.T) {
133154
c := newConversation(otrV3{}, rand.Reader)
134155
c.ourInstanceTag = 0x103

inject_message.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@ type injections struct {
55
}
66

77
// injectMessage will promise to send the messages now or later
8+
// The Injected Messages are promised to be well formed valid messages
9+
// including fragmentation and encoding
810
func (c *Conversation) injectMessage(vm ValidMessage) {
911
c.injections.messages = append(c.injections.messages, vm)
1012
}
1113

12-
func (c *Conversation) withInjections(vms []ValidMessage) []ValidMessage {
14+
func (c *Conversation) withInjects(vms []ValidMessage) []ValidMessage {
1315
msgs := c.injections.messages
1416
c.injections.messages = c.injections.messages[0:0]
1517
return append(vms, msgs...)
1618
}
19+
20+
func (c *Conversation) withInjectionsPlain(plain MessagePlaintext, vms []ValidMessage, err error) (MessagePlaintext, []ValidMessage, error) {
21+
return plain, c.withInjects(vms), err
22+
}
23+
24+
func (c *Conversation) withInjections(vms []ValidMessage, err error) ([]ValidMessage, error) {
25+
return c.withInjects(vms), err
26+
}

otrv3.go

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func (c *Conversation) generateInstanceTag() error {
129129

130130
func malformedMessage(c *Conversation) {
131131
messageEventReceivedMalformedMessage(c)
132+
c.generatePotentialErrorMessage(ErrorCodeMessageMalformed)
132133
}
133134

134135
func (v otrV3) parseMessageHeader(c *Conversation, msg []byte) ([]byte, []byte, error) {

receive.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (c *Conversation) receiveDecoded(message messageWithHeader) (plain MessageP
113113
messageEventReceivedMalformedMessage(c)
114114
e = ErrorCodeMessageMalformed
115115
}
116-
plain = MessagePlaintext(c.generatePotentialErrorMessage([]ValidMessage{ValidMessage(plain)}, e)[0])
116+
c.generatePotentialErrorMessage(e)
117117
}
118118
} else {
119119
toSend, err = c.potentialAuthError(c.receiveAKE(msgType, messageBody))
@@ -135,7 +135,7 @@ func (c *Conversation) Receive(m ValidMessage) (plain MessagePlaintext, toSend [
135135
var messagesToSend []messageWithHeader
136136
switch msgType {
137137
case msgGuessError:
138-
return c.receiveErrorMessage(message)
138+
return c.withInjectionsPlain(c.receiveErrorMessage(message))
139139
case msgGuessQuery:
140140
messagesToSend, err = c.receiveQueryMessage(message)
141141
case msgGuessTaggedPlaintext:
@@ -147,13 +147,13 @@ func (c *Conversation) Receive(m ValidMessage) (plain MessagePlaintext, toSend [
147147
case msgGuessFragment:
148148
c.fragmentationContext, err = c.receiveFragment(c.fragmentationContext, message)
149149
if fragmentsFinished(c.fragmentationContext) {
150-
return c.Receive(c.fragmentationContext.frag)
150+
return c.withInjectionsPlain(c.Receive(c.fragmentationContext.frag))
151151
}
152152
case msgGuessUnknown:
153153
messageEventReceivedUnrecognizedMessage(c)
154154
case msgGuessDHCommit, msgGuessDHKey, msgGuessRevealSig, msgGuessSignature, msgGuessData:
155155
plain, messagesToSend, err = c.receiveEncoded(encodedMessage(message))
156156
}
157157

158-
return c.toSendEncoded(plain, messagesToSend, err)
158+
return c.withInjectionsPlain(c.toSendEncoded(plain, messagesToSend, err))
159159
}

send.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ func (c *Conversation) Send(m ValidMessage) ([]ValidMessage, error) {
1414

1515
switch c.msgState {
1616
case plainText:
17-
return c.sendMessageOnPlaintext(message)
17+
return c.withInjections(c.sendMessageOnPlaintext(message))
1818
case encrypted:
19-
return c.sendMessageOnEncrypted(message)
19+
return c.withInjections(c.sendMessageOnEncrypted(message))
2020
case finished:
2121
messageEventConnectionEnded(c)
22-
return nil, errors.New("otr: cannot send message because secure conversation has finished")
22+
return c.withInjections(nil, errors.New("otr: cannot send message because secure conversation has finished"))
2323
}
2424

25-
return nil, errors.New("otr: cannot send message in current state")
25+
return c.withInjections(nil, errors.New("otr: cannot send message in current state"))
2626
}
2727

2828
func (c *Conversation) sendMessageOnPlaintext(message ValidMessage) ([]ValidMessage, error) {
@@ -41,19 +41,18 @@ func (c *Conversation) sendMessageOnPlaintext(message ValidMessage) ([]ValidMess
4141
return []ValidMessage{makeCopy(message)}, nil
4242
}
4343

44-
func (c *Conversation) generatePotentialErrorMessage(before []ValidMessage, ec ErrorCode) []ValidMessage {
44+
func (c *Conversation) generatePotentialErrorMessage(ec ErrorCode) {
4545
if c.getEventHandler().WishToHandleErrorMessage() {
4646
msg := c.getEventHandler().HandleErrorMessage(ec)
47-
return []ValidMessage{append(append(errorMarker, ' '), msg...)}
47+
c.injectMessage(append(append(errorMarker, ' '), msg...))
4848
}
49-
return before
5049
}
5150

5251
func (c *Conversation) sendMessageOnEncrypted(message ValidMessage) ([]ValidMessage, error) {
5352
result, err := c.createSerializedDataMessage(message, messageFlagNormal, []tlv{})
5453
if err != nil {
5554
messageEventEncryptionError(c)
56-
result = c.generatePotentialErrorMessage(result, ErrorCodeEncryptionError)
55+
c.generatePotentialErrorMessage(ErrorCodeEncryptionError)
5756
}
5857

5958
return result, err

0 commit comments

Comments
 (0)