~ubuntu-branches/ubuntu/trusty/libotr2/trusty

« back to all changes in this revision

Viewing changes to UPGRADING

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2012-11-05 01:06:26 UTC
  • Revision ID: package-import@ubuntu.com-20121105010626-4m3hldpaz3jfr3wb
Tags: upstream-3.2.1
ImportĀ upstreamĀ versionĀ 3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Table of Contents
 
2
 
 
3
1. Introduction
 
4
2. Major Additions
 
5
2.1. Fragmentation
 
6
2.2. Socialist Millionaires' Protocol
 
7
3. Required Changes
 
8
3.1. OtrlMessageAppOps Callbacks
 
9
3.1.1. Max Message Size
 
10
3.1.2. Account Name
 
11
3.2. Using Fragmentation
 
12
3.3. Using SMP
 
13
3.3.1. Initiating
 
14
3.3.2. Responding
 
15
3.3.3. Aborting
 
16
3.3.4. Control Flow and Errors
 
17
3.4. Miscellaneous
 
18
 
 
19
1. Introduction
 
20
 
 
21
This file contains information about the changes between the 3.0.0 and
 
22
the 3.2.0 APIs for libotr.  Note that, as a minor release, applications
 
23
compiled against 3.0.0 will continue to work with 3.2.0.  This document
 
24
explains how to add the new functionality in 3.2.0.
 
25
 
 
26
2. Major Additions
 
27
 
 
28
This section describes the new features in OTR 3.2.0 along with a short
 
29
history or motivation for each.
 
30
 
 
31
2.1. Fragmentation  [Added in 3.1.0]
 
32
 
 
33
Most IM networks supported by Pidgin have fixed maximum message sizes
 
34
(MMS) of approximately 1-3 kB.  The longer messages in the initial key
 
35
exchange and the new socialist millionaires' protocol may exceed these
 
36
common MMS values.  To allow these protocols to work properly even over
 
37
networks with low MMS values, support for fragmentation was added.
 
38
 
 
39
OTR version 3.0.0 added support for recombining message fragments to
 
40
recover the original message.  Now that users may be assumed to be able to
 
41
handle message fragments, support for fragmenting and sending large
 
42
messages has been added to OTR 3.2.0.
 
43
 
 
44
2.2. Socialist Millionaires' Protocol  [Added in 3.1.0, revised in 3.2.0]
 
45
 
 
46
In version 3.0.0, the only method available to authenticate a buddy was
 
47
fingerprint verification.  However, many users who are unfamiliar with
 
48
cryptography do not understand what a fingerprint is or how it is useful.
 
49
Also, the verification itself relied on the user obtaining an authentic
 
50
copy of the other party's fingerprint somehow.  The simplest way to do so
 
51
may be to relay the displayed hexadecimal values during a phone call,
 
52
but this is a large enough hassle that many users omit fingerprint
 
53
verification altogether.
 
54
 
 
55
To allow for a method of authentication that is both easier to understand
 
56
and easier to use, OTR version 3.2.0 includes the Socialist Millionaires'
 
57
Protocol (SMP).  SMP runs as follows: each user inputs a secret string,
 
58
say "x" and "y".  They then exchange a series of messages which reveal
 
59
the value of (x==y), but no additional information about the inputs.
 
60
This allows users to determine whether they hold the same secret
 
61
information with no danger of revealing that secret to an attacker.
 
62
 
 
63
To see how this is useful for authentication in OTR, assume that Alice
 
64
and Bob are chatting over OTR for the first time, though they know each
 
65
other well in real life.  Alice may send Bob the following message:
 
66
"Let's make our shared secret the name of that restaurant we both like
 
67
in Ottawa."
 
68
 
 
69
Now Alice and Bob run SMP.  If Alice is actually talking to Bob directly,
 
70
then they will both type in the same restaurant name and SMP will return
 
71
success (x==y).  However, if an attacker is impersonating Bob or trying
 
72
to eavesdrop on the conversation, they will have no idea which restaurant
 
73
Alice has in mind, and will type in an incorrect value, causing SMP to
 
74
fail.  Note that for security reasons, the values compared in the SMP
 
75
are actually hashes of several pieces of data, including both parties'
 
76
fingerprints, along with their respective secrets.  The users, however,
 
77
are never exposed to this additional data.
 
78
 
 
79
Thus, SMP turns the problem of obtaining an authentic copy of a
 
80
fingerprint into the much simpler problem of obtaining any shared secret,
 
81
or simply of drawing on shared experiences to generate one.
 
82
 
 
83
For detailed information on how SMP works, see the paper by Boudot,
 
84
Schoenmakers and Traore titled "A Fair and Efficient Solution to the
 
85
Socialist Millionaires Problem" (2001), on which our solution is based.
 
86
 
 
87
3. Required Changes  [Added in 3.1.0]
 
88
 
 
89
3.1. OtrlMessageAppOps Callbacks
 
90
 
 
91
Three new callbacks have been added to the end of OtrlMessageAppOps.  If
 
92
the version number passed to otrl_init is less than 3.1.0 then libotr will
 
93
not call any of the new callbacks.  As well, you may disable individual
 
94
callbacks by setting them to NULL.  In either case, libotr will revert to
 
95
the standard behaviour of version 3.0.0.
 
96
 
 
97
3.1.1. Max Message Size
 
98
 
 
99
The first new callback has the following signature:
 
100
 
 
101
    int (*max_message_size)(void *opdata, ConnContext *context);
 
102
 
 
103
This method is called whenever a message is about to be sent with
 
104
fragmentation enabled.  The return value is checked against the size of
 
105
the message to be sent to determine whether fragmentation is necessary.
 
106
 
 
107
Although the maximum message size depends on a number of factors, we
 
108
found experimentally that the following rough values based solely on the
 
109
(pidgin) protocol name work well:
 
110
    "prpl-msn",   1409
 
111
    "prpl-icq",   2346
 
112
    "prpl-aim",   2343
 
113
    "prpl-yahoo", 832
 
114
    "prpl-gg",    1999
 
115
    "prpl-irc",   417
 
116
    "prpl-oscar", 2343
 
117
 
 
118
Setting max_message_size to NULL will disable the fragmentation of all
 
119
sent messages; returning 0 from this callback will disable fragmentation
 
120
of a particular message.  The latter is useful, for example, for
 
121
protocols like XMPP (Jabber) that do not require fragmentation at all.
 
122
 
 
123
3.1.2. Account Name
 
124
 
 
125
The other two new callbacks have the following signatures: 
 
126
 
 
127
    const char *(*account_name)(void *opdata, const char *account,
 
128
            const char *protocol);
 
129
    void (*account_name_free)(void *opdata, const char *account_name);
 
130
 
 
131
Normally, if an error message needs to be sent from Alice to Bob,
 
132
containing Alice's account name, the value of ConnContext->accountname
 
133
will be used.  However, if this default name is unsuitable for your
 
134
application, you can use the above methods to provide replacement values
 
135
for displayed account names.
 
136
 
 
137
account_name is called when libotr requires a human-readable version of
 
138
an account name.  account_name_free is called once the name has
 
139
been used, and the memory allocated by account_name (if any) must be
 
140
released.
 
141
 
 
142
Setting account_name to NULL will cause libotr to use
 
143
ConnContext->accountname as the displayed name for an account.
 
144
 
 
145
3.2. Using Fragmentation  [Added in 3.1.0]
 
146
 
 
147
To make use of fragmentation, first make sure that the max_message_size
 
148
callback described in 3.1.1. has been implemented.  Then, whenever you
 
149
would normally send a message through your IM client, call
 
150
otrl_message_fragment_and_send instead:
 
151
 
 
152
gcry_error_t otrl_message_fragment_and_send(const OtrlMessageAppOps *ops,
 
153
        void *opdata, ConnContext *context, const char *message,
 
154
        OtrlFragmentPolicy fragPolicy, char **returnFragment);
 
155
 
 
156
Here, message is the original, encrypted, unfragmented message.
 
157
This method will break the message into fragments and send either all of
 
158
them or almost all of them according to the OtrlFragmentPolicy:
 
159
 
 
160
OTRL_FRAGMENT_SEND_ALL            sends all fragments at once
 
161
OTRL_FRAGMENT_SEND_ALL_BUT_FIRST  sends all but the first fragment
 
162
OTRL_FRAGMENT_SEND_ALL_BUT_LAST   sends all but the last fragment
 
163
 
 
164
You may wish to use one of the latter two options if you still wish to
 
165
pass a message through your IM client.  In this case, the unsent
 
166
fragment will be returned in returnFragment and should be sent as a
 
167
regular message.  In order to reassemble the fragments, however, they
 
168
must be received in order, so at most one of the latter two options
 
169
will result in readable messages.
 
170
 
 
171
3.3. Using SMP  [Added in 3.1.0, revised in 3.2.0]
 
172
 
 
173
Recall from section 2.2. above that SMP takes one input string from each
 
174
user and outputs either failure or success.
 
175
 
 
176
3.3.1. Initiating
 
177
 
 
178
If you wish to initiate SMP for a user named Alice, you would use
 
179
otrl_message_initiate_smp.
 
180
 
 
181
void otrl_message_initiate_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
 
182
        void *opdata, ConnContext *context, const unsigned char *secret,
 
183
        size_t secretlen);
 
184
 
 
185
Here, secret and secretlen describe the secret text as entered by Alice,
 
186
for example, ("kitten", 6).  The other parameters are common to many
 
187
otrl_message functions.  This method will cause a message to be sent
 
188
containing an appropriate OTRL_TLV_SMP1 (see below).
 
189
 
 
190
3.3.2. Responding
 
191
 
 
192
If you wish to continue SMP by supplying the secret for a second user
 
193
named Bob, you would use otrl_message_respond_smp:
 
194
 
 
195
void otrl_message_respond_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
 
196
        void *opdata, ConnContext *context, const unsigned char *secret,
 
197
        size_t secretlen);
 
198
 
 
199
The arguments for this method are the same as otrl_message_initiate_smp.
 
200
This method will send a message with an appropriate OTRL_TLV_SMP2
 
201
(see below).
 
202
 
 
203
3.3.3. Aborting
 
204
 
 
205
If you wish to abort SMP for any reason, including errors occuring
 
206
during the protocol, you should use otrl_message_abort_smp:
 
207
 
 
208
void otrl_message_abort_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
 
209
        void *opdata, ConnContext *context);
 
210
 
 
211
This method will cause the other user to abandon the current state of
 
212
SMP by sending an appropriate OTRL_TLV_SMP_ABORT (see below).
 
213
 
 
214
3.3.4. Control Flow and Errors
 
215
 
 
216
The protocol itself consists of 4 messages passed between the two users,
 
217
say Alice and Bob.  These messages are identified through their TLVs:
 
218
 
 
219
OTRL_TLV_SMP1       The initial message, containing a commitment to
 
220
                      Alice's secret
 
221
OTRL_TLV_SMP1Q      Like OTRL_TLV_SMP1, but also containing a question
 
222
                      to display to Bob
 
223
OTRL_TLV_SMP2       A response containing a commitment to Bob's secret
 
224
OTRL_TLV_SMP3       The next message in the chain, from Alice to Bob
 
225
OTRL_TLV_SMP4       The final message in the chain, from Bob to Alice
 
226
OTRL_TLV_SMP_ABORT  Indicates an error has occurred. Will reset SMP state
 
227
 
 
228
To determine whether the protocol is proceeding correctly, additional
 
229
information has been added to ConnContext.  You may access
 
230
context->smstate->nextExpected to find out which TLV should come next,
 
231
so you can compare this to what was actually received and take an
 
232
appropriate action.  The value is of type NextExpectedSMP and could be
 
233
any of:
 
234
 
 
235
OTRL_SMP_EXPECT1   Next SMP TLV should be OTRL_TLV_SMP1
 
236
OTRL_SMP_EXPECT2   Next SMP TLV should be OTRL_TLV_SMP2
 
237
OTRL_SMP_EXPECT3   Next SMP TLV should be OTRL_TLV_SMP3
 
238
OTRL_SMP_EXPECT4   Next SMP TLV should be OTRL_TLV_SMP4
 
239
 
 
240
If at any point, an SMP TLV of an unexpected type is received, the
 
241
protocol should abort.  Also, if the correct TLV type is received, then
 
242
the state should be updated accordingly.  A typical control flow looks
 
243
like this:
 
244
 
 
245
    OtrlTLV *tlvs = NULL;
 
246
    OtrlTLV *tlv = NULL;
 
247
    [Initialize tlvs to the list of tlvs.  This can be done
 
248
     as part of otrl_message_receiving.]
 
249
 
 
250
    ConnContext *context = [correct context];
 
251
    NextExpectedSMP nextMsg = context->smstate->nextExpected;
 
252
 
 
253
    if (context->smstate->sm_prog_state == OTRL_SMP_PROG_CHEATED) {
 
254
        otrg_plugin_abort_smp(context);
 
255
        otrg_dialog_update_smp(context, 0.0);
 
256
        context->smstate->nextExpected = OTRL_SMP_EXPECT1;
 
257
        context->smstate->sm_prog_state = OTRL_SMP_PROG_OK;
 
258
    } else {
 
259
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q);
 
260
        if (tlv) {
 
261
            if (nextMsg != OTRL_SMP_EXPECT1)
 
262
                [abort SMP];
 
263
            else {
 
264
                char *question = (char *)tlv->data;
 
265
                char *eoq = memchr(question, '\0', tlv->len);
 
266
                if (eoq) {
 
267
                    [prompt the user with question, get the response,
 
268
                        and continue SMP];
 
269
                }
 
270
            }
 
271
        }
 
272
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
 
273
        if (tlv) {
 
274
            if (nextMsg != OTRL_SMP_EXPECT1)
 
275
                [abort SMP];
 
276
            else {
 
277
                [get secret from user and continue SMP];
 
278
            }
 
279
        }
 
280
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
 
281
        if (tlv) {
 
282
            if (nextMsg != OTRL_SMP_EXPECT2)
 
283
                [abort SMP];
 
284
            else {
 
285
                // If we received TLV2, we will send TLV3 and expect TLV4
 
286
                context->smstate->nextExpected = OTRL_SMP_EXPECT4;
 
287
            }
 
288
        }
 
289
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
 
290
        if (tlv) {
 
291
            if (nextMsg != OTRL_SMP_EXPECT3)
 
292
                [abort SMP];
 
293
            else {
 
294
                // If we received TLV3, we will send TLV4
 
295
                // We will not expect more messages, so prepare for next SMP
 
296
                context->smstate->nextExpected = OTRL_SMP_EXPECT1;
 
297
                // Report result to user
 
298
            }
 
299
        }
 
300
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4);
 
301
        if (tlv) {
 
302
            if (nextMsg != OTRL_SMP_EXPECT4)
 
303
                [abort SMP];
 
304
            else {
 
305
                // We will not expect more messages, so prepare for next SMP
 
306
                context->smstate->nextExpected = OTRL_SMP_EXPECT1;
 
307
                // Report result to user
 
308
            }
 
309
        }
 
310
        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
 
311
        if (tlv) {
 
312
            // The message we are waiting for will not arrive, so reset
 
313
            // and prepare for the next SMP
 
314
            context->smstate->nextExpected = OTRL_SMP_EXPECT1;
 
315
        }
 
316
    }
 
317
 
 
318
To report the result to the user after receiving OTRL_TLV_SMP3 or
 
319
OTRL_TLV_SMP4, check whether context->active_fingerprint->trust is a
 
320
non-empty string.  (That is, check that it's not NULL, and that its
 
321
first character is not '\0'.)  If that is the case, then the SMP
 
322
completed successfully.  Otherwise, the parties entered different secrets.
 
323
 
 
324
3.4 Miscellaneous
 
325
 
 
326
b64.h underwent a minor change in OTR 3.1.0.  It was purely a
 
327
housekeeping change and should not require any changes to dependent code.
 
328
 
 
329
The arguments to otrl_base64_encode and otrl_base64_decode did not agree
 
330
in terms of which were of type char* and which were unsigned char*
 
331
instead.  This has been corrected.  The new method signatures are:
 
332
 
 
333
size_t otrl_base64_encode(char *base64data, const unsigned char *data,
 
334
        size_t datalen);
 
335
size_t otrl_base64_decode(unsigned char *data, const char *base64data,
 
336
        size_t base64len);
 
337