README 15.7 KB
Newer Older
cypherpunk's avatar
cypherpunk committed
1
	      Off-the-Record Messaging Library and Toolkit
Ian Goldberg's avatar
Ian Goldberg committed
2
			  v4.1.1, 9 Mar 2016
cypherpunk's avatar
cypherpunk committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

This is a library and toolkit which implements Off-the-Record (OTR) Messaging.

OTR allows you to have private conversations over IM by providing:
 - Encryption
   - No one else can read your instant messages.
 - Authentication
   - You are assured the correspondent is who you think it is.
 - Deniability
   - The messages you send do _not_ have digital signatures that are
     checkable by a third party.  Anyone can forge messages after a
     conversation to make them look like they came from you.  However,
     _during_ a conversation, your correspondent is assured the messages
     he sees are authentic and unmodified.
 - Perfect forward secrecy
   - If you lose control of your private keys, no previous conversation
     is compromised.

For more information on Off-the-Record Messaging, see
22
https://otr.cypherpunks.ca/
cypherpunk's avatar
cypherpunk committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

LIBRARY USAGE

1. Initialization

Before you call any other libotr routine, you need to initialize the
library.  The easiest way to do that is to include proto.h, and use the
macro:

    OTRL_INIT;

somewhere early in your program.  This should be called only once.

You will also need an OtrlUserState.  An OtrlUserState encapsulates the
list of known fingerprints and the list of private keys, so it should be
"one per user".  Many OTR-enabled programs (such as IM clients) only have a 
single user, so for them, you can just create a single one, and use it
40
throughout.  Create an OtrlUserState as follows:
cypherpunk's avatar
cypherpunk committed
41
42
43
44
45
46
47
48
49
50
51

    userstate = otrl_userstate_create();

If you need to free an OtrlUserState:

    otrl_userstate_free(userstate);

To read stored private keys:

    otrl_privkey_read(userstate, privkeyfilename);

Rob Smits's avatar
Rob Smits committed
52
53
54
55
To read stored instance tags:

    otrl_instag_read(userstate, instagfilename);

cypherpunk's avatar
cypherpunk committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
To read stored fingerprints:

    otrl_privkey_read_fingerprints(userstate, fingerprintfilename,
	    add_app_info, add_app_info_data);

add_app_info is a function that will be called in the event that a new
ConnContext is created.  It will be passed the add_app_info_data that
you supplied, as well as a pointer to the new ConnContext.  You can use
this to add application-specific information to the ConnContext using
the "context->app" field, for example.  If you don't need to do this,
you can pass NULL for the last two arguments of
otrl_privkey_read_fingerprints.

2. Setting up the UI functions

You need to let the library know how to do any UI it might require
(error messages, confirming new fingerprints, etc.).  To this end, you
need to define a number of UI functions, and collect them in a
OtrlMessageAppOps struct.

The first parameter of every UI function is "void *opdata".  This is a
pointer you pass to the library, and it will pass back (opaquely) to the
UI functions when it calls them.  You can use this to keep track of
state or any other information.

You will need to include proto.h and message.h, and you can find a list
of the UI functions in message.h.

3. Sending messages

When you have a message you're about to send, you'll need to know four
Rob Smits's avatar
Rob Smits committed
87
88
89
90
91
92
93
94
things: you account name, the protocol id, the name of the recipient, 
their instance tag, and the message.

OTR protocol version 3 introduces the notion of "instance tags." A
client may be logged into the same account multiple times from different
locations. An instance tag is intended to differentiate these clients. 
When sending a message, you may also specify a particular instance tag, 
or use meta instance tags like OTRL_INSTAG_MOST_SECURE.
cypherpunk's avatar
cypherpunk committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

The protocol id is just a unique string that is used to distinguish
the user foo on AIM from the user foo on MSN, etc.  It can be anything
you like, so long as you're consistent, but if you've got nothing better
to use, you may as well use the ids from gaim.  (Programs that use the
same protocol ids can share fingerprint and private key files.)  The
gaim protocol id for AIM/ICQ is "prpl-oscar".

Note that a name does not uniquely identify a user (as shown by the
"foo" example above).  Even if you know both the name and the protocol,
it may not identify the user, since there may be multiple "foo" users on
IRC, on different servers.  But the *three* items (your account name,
protocol id, their name) _must_ uniquely identify a user, so your
account name needs to include any network identifier, such as a server
name.  Examples would be "foo@irc.freenode.net" or "foo@jabber.org".
Protocols such as AIM that do not have separate networks can just use
"foo", of course.

To encrypt the message (if necessary; the library keeps track of which
users you have secure connections to, so you should *always* call this
next function), simply do this:

    gcry_error_t err;
    char *newmessage = NULL;

    err = otrl_message_sending(userstate, &ui_ops, opdata, accountname,
Rob Smits's avatar
Rob Smits committed
121
122
123
	    protocolid, recipient_name, instag, message, tlvs, 
	    &newmessage, fragPolicy, contextp, add_app_info, 
	    add_app_info_data);
cypherpunk's avatar
cypherpunk committed
124
125
126
127
128
129
130

add_app_info and add_app_info_data are as above, and may be NULL.

tlvs should usually be NULL.  If it's not, then it points to a chain of
OtrlTLVs which represent machine-readable data to send along with this
message.

Rob Smits's avatar
Rob Smits committed
131
132
133
If contextp is not NULL, it will be set to the context that was used
for sending the message.

cypherpunk's avatar
cypherpunk committed
134
135
136
137
138
139
140
141
If err is non-zero, then the library tried to encrypt the message,
but for some reason failed.  DO NOT send the message in the clear in
that case.

If newmessage gets set by the call to something non-NULL, then you
should replace your message with the contents of newmessage, and
send that instead.

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
Once the message is encrypted, it may still be too large to send over
the network in a single piece.  To check the maximum message size and
break your message into fragments if necessary, do this:

    gcry_error_t err;
    char *extrafragment = NULL;

    err = otrl_message_fragment_and_send(&ui_ops, opdata, context,
	    message, fragmentPolicy, extrafragment);

fragmentPolicy determines which, if any, fragments to return instead
of sending them immediately.  For example, you may wish to send all 
fragments except the last one, which is handled differently.  Valid
policies may be found in proto.h.

If err returns a nonzero value from fragment_and_send, the application
tried to break your message into fragments but failed for some reason.
You may still attempt to send the original message, but it might be
rejected if it too large.

cypherpunk's avatar
cypherpunk committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
When you're done with newmessage, you must call

    otrl_message_free(newmessage)

4. Receiving messages

Receiving messages is similarly straightforward.  Again, you need to
know four things: your account name, the protocol id, the sender's name,
and the message.

    int ignore_message;
    char *newmessage = NULL;

    ignore_message = otrl_message_receiving(userstate, &ui_ops, opdata,
	    accountname, protocolid, sender_name, message, &newmessage,
Rob Smits's avatar
Rob Smits committed
177
	    &tlvs, contextp, add_app_info, add_app_info_data);
cypherpunk's avatar
cypherpunk committed
178
179
180

add_app_info and add_app_info_data are as above, and may be NULL.

Rob Smits's avatar
Rob Smits committed
181
182
183
If contextp is not NULL, it will be set to the context that was used
for receiving the message.

cypherpunk's avatar
cypherpunk committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
If otrl_message_receiving returns 1, then the message you received was
an internal protocol message, and no message should be delivered to the
user.

If it returns 0, then check if newmessage was set to non-NULL.  If so,
replace the received message with the contents of newmessage, and
deliver that to the user instead.  You must call
otrl_message_free(newmessage) when you're done with it.

If otrl_message_receiving returns 0 and newmessage is NULL, then this
was an ordinary, non-OTR message, which should just be delivered to the
user without modification.

If tlvs is set to non-NULL, then there is machine-readable data that was
sent along with this message.  Call otrl_tlv_free(tlvs) when you're done
dealing with it (or ignoring it).

201
202
203
204
205
206
207
208
5. Socialist Millionaires' Protocol

The Socialist Millionaires' Protocol (SMP) is a way to detect
eavesdropping and man-in-the-middle attacks without requiring users to
work with fingerprints.  This feature was added to OTR starting in
version 3.1.0.  To learn how to modify your application to use SMP, read
the UPGRADING file.

cypherpunk's avatar
cypherpunk committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
TOOLKIT

Along with the library, this package comes with the OTR Messaging
Toolkit.  This toolkit is useful for analyzing and/or forging OTR
messages.  Why do we offer this?  Primarily, to make absolutely sure
that transcripts of OTR conversations are really easy to forge after the
fact.  [Note that *during* an OTR conversation, messages can't be forged
without real-time access to the secret keys on the participants'
computers, and in that case, all security has already been lost.]
Easily forgeable transcripts help us provide the "Deniability" property:
if someone claims you said something over OTR, they'll have no proof, as
anyone at all can modify a transcript to make it say whatever they like,
and still have all the verification come out correctly.

Here are the six programs in the toolkit:

 - otr_parse
   - Parse OTR messages given on stdin, showing the values of all the
227
     fields in OTR protocol messages.
cypherpunk's avatar
cypherpunk committed
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

 - otr_sesskeys our_privkey their_pubkey
   - Shows our public key, the session id, two AES and two MAC keys
     derived from the given Diffie-Hellman keys (one private, one public).

 - otr_mackey aes_enc_key
   - Shows the MAC key derived from the given AES key.

 - otr_readforge aes_enc_key [newmsg]
   - Decrypts an OTR Data message using the given AES key, and displays
     the message, if the key was correct.
   - If newmsg is given, replace the message with that one, encrypt
     and MAC it properly, and output the resulting OTR Data Message.
     This works even if the given key was not correct for the original
     message, so as to enable complete forgeries.

 - otr_modify mackey old_text new_text offset
   - Even if you can't read the data because you don't know either
     the AES key or the Diffie-Hellman private key, but you can make a
     good guess that the substring "old_text" appears at the given
     offset in the message, replace the old_text with the new_text
     (which must be of the same length), recalculate the MAC with the
     given mackey, and output the resulting Data message.
   - Note that, even if you don't know any text in an existing message,
     you can still forge messages of your choice using the otr_readforge
     command, above.

Rob Smits's avatar
Rob Smits committed
255
256
 - otr_remac mackey sender_instance receiver_instance flags keyid keyid
   pubkey counter encdata revealed_mackeys
cypherpunk's avatar
cypherpunk committed
257
258
259
260
261
262
263
264
   - Make a new OTR Data Message, with the given pieces (note that the
     data part is already encrypted).  MAC it with the given mackey.

NOTES

Please send your bug reports, comments, suggestions, patches, etc. to us
at the contact address below.

Rob Smits's avatar
Rob Smits committed
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
In otrl_message_sending, specifying an instance tag allows you to send a
message to a particular session of a buddy who is logged in multiple times
with an otr-enabled client. The OTRL_INSTAG_RECENT_RECEIVED meta-instance
relies on the time that libotr processed the most recent message. Meta-
instance tags resolve to actual instance tags before a message is sent. An
instant messaging network may not agree on which session of the remote party is
the most recent, e.g., due to underlying network race conditions. If the
behaviour of an instant messaging network is to only deliver to the most recent,
and libotr and the network disagree on which session is the most recent, the
other party will not process the given message. That is, the instant messaging
network will deliver the message to the session whose actual instance tag does
not match the addressed instance tag. Also note that OTRL_INSTAG_BEST also
prefers more recent instance tags in the case of multiple instances with the
same "best" status (most secure). In this case, the most recent has a
resolution of one second.

If otrl_message_sending is called with an original_msg that contains the text
"?OTR?", this is a signal to initiate or refresh an OTR session. There is
currently no way to indicate if this text was actually typed in by a user and
part of a conversation (e.g., someone communicating instructions on how to
refresh OTR). In the future, we may allow a policy to specify whether "?OTR?"
is a signal to start OTR, or just an ordinary message for encrypted and
unencrypted conversations.

cypherpunk's avatar
cypherpunk committed
289
290
291
292
293
MAILING LISTS

There are three mailing lists pertaining to Off-the-Record Messaging:

otr-announce:
294
    https://lists.cypherpunks.ca/mailman/listinfo/otr-announce/
cypherpunk's avatar
cypherpunk committed
295
296
297
298
    *** All users of OTR software should join this. ***  It is used to
    announce new versions of OTR software, and other important information.

otr-users:
299
    https://lists.cypherpunks.ca/mailman/listinfo/otr-users/
cypherpunk's avatar
cypherpunk committed
300
301
302
    Discussion of usage issues related to OTR Messaging software.

otr-dev:
303
    https://lists.cypherpunks.ca/mailman/listinfo/otr-dev/
cypherpunk's avatar
cypherpunk committed
304
305
306
307
308
309
310
311
    Discussion of OTR Messaging software development.

LICENSE

The Off-the-Record Messaging library (in the src directory) is
covered by the following (LGPL) license:

    Off-the-Record Messaging library
312
    Copyright (C) 2004-2016  Ian Goldberg, David Goulet, Rob Smits,
313
314
                             Chris Alexander, Willy Lew, Lisa Du,
			     Nikita Borisov
cypherpunk's avatar
cypherpunk committed
315
316
317
318
319
320
321
322
323
324
325
326
327
			     <otr@cypherpunks.ca>

    This library is free software; you can redistribute it and/or
    modify it under the terms of version 2.1 of the GNU Lesser General
    Public License as published by the Free Software Foundation.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    There is a copy of the GNU Lesser General Public License in the
    COPYING.LIB file packaged with this library; if you cannot find it,
Rob Smits's avatar
Rob Smits committed
328
329
    write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
    Floor, Boston, MA 02110-1301 USA
cypherpunk's avatar
cypherpunk committed
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
The library comes with a test suite (in the tests directory), which is
covered by the following (GPL) license:

    Copyright (C) 2014   Julien Voisin <julien.voisin@dustri.org>,
                         David Goulet <dgoulet@ev0ke.net>

    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License, version 2 only, as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    more details.

    You should have received a copy of the GNU General Public License along with
    this program; if not, write to the Free Software Foundation, Inc., 51
    Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

cypherpunk's avatar
cypherpunk committed
350
351
352
353
The Off-the-Record Messaging Toolkit (in the toolkit directory) is covered
by the following (GPL) license:

    Off-the-Record Messaging Toolkit
354
355
    Copyright (C) 2004-2014  Ian Goldberg, David Goulet, Rob Smits,
                             Chris Alexander, Nikita Borisov
cypherpunk's avatar
cypherpunk committed
356
357
358
359
360
361
362
363
364
365
366
367
368
		             <otr@cypherpunks.ca>

    This program is free software; you can redistribute it and/or modify
    it under the terms of version 2 of the GNU General Public License as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    There is a copy of the GNU General Public License in the COPYING file
    packaged with this toolkit; if you cannot find it, write to the Free
Rob Smits's avatar
Rob Smits committed
369
370
    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301 USA
cypherpunk's avatar
cypherpunk committed
371
372
373
374
375
376

CONTACT

To report problems, comments, suggestions, patches, etc., you can email
the authors:

377
378
Ian Goldberg, David Goulet, Rob Smits, Chris Alexander, Lisa Du,
Nikita Borisov
Rob Smits's avatar
Rob Smits committed
379
<otr@cypherpunks.ca>
cypherpunk's avatar
cypherpunk committed
380
381

For more information on Off-the-Record Messaging, visit
382
https://otr.cypherpunks.ca/