@c -*-texinfo-*-

@node otr
@section Off-the-Record Messaging
The @code{(industria otr)} library provides Off-the-Record
Messaging (OTR), which is a security protocol for private chat. It can
be tunneled over any protocol that guarantees in-order delivery
(e.g.@: IRC or XMPP). It provides encryption, authentication,
deniability and perfect forward secrecy.

This library does not manage user identities, which is something the
OTR Development Team's C library does. This choice was made to keep
the implementation simple and focused on the protocol only.

The website for OTR is @url{http://www.cypherpunks.ca/otr/}.

@deffn Procedure otr-message? str
Returns @code{#t} if @var{str}, which is a message from a remote
party, contains an OTR message. If it is an OTR message you should
look up the OTR state that corresponds to the remote party (possibly
make a new state) and call @code{otr-update!}.
@end deffn

@deffn Procedure make-otr-state dsa-key mss [instance-tag [versions]]
Creates an OTR state value given the private DSA key @var{dsa-key} and
a maximum segment size @var{mss}. The state is used to keep track of
session keys and incoming message fragments.

The @var{dsa-key} must have a 160-bit q-parameter because of details
in the protocol and limitations of other implementations. A 1024-bit
DSA key will work. @xref{crypto dsa}.

The maximum segment size @var{mss} is used to split long OTR messages
into smaller parts when OTR is used over a protocol with a maximum
message size, e.g.@: IRC.

If an @var{instance-tag} is specified it must be a 32-bit integer not
less than @code{#x100}. If it is omitted or @code{#f} an instance tag
will be randomly generated. OTR version 3 uses the instance tags to
identify which OTR state messages belongs to. Be sure to read the
documentation for @code{otr-state-our-instance-tag}. New for Industria
1.5.

If @var{versions} is not omitted it must be a list of acceptable OTR
protocol versions. The default is @code{(2 3)}. New for Industria 1.5.
@end deffn

@deffn Procedure otr-update! state str
Processes the @var{str} message, which came from the remote party,
and updates the @var{state}. Use @code{otr-empty-queue!} to retrieve
scheduled events.
@end deffn

@deffn Procedure otr-send-encrypted! state msg
@c [flags [tlv]] ...
This is used to send a message to the remote party. It encrypts and
enqueues the @var{msg} bytevector and updates the @var{state}.
Use @code{otr-empty-queue!} to retrieve the encrypted and formatted
messages that should be sent to the remote party.

The @var{msg} must not contain a NUL (0) byte.
@c TODO: document the tlv parameters when there's a procedure for
@c formatting them, and a way to receive tlv's from the remote party.
@c Optionally you can send one or more @dfn{type/length/value} (TLV)
@c bytevectors. A @var{tlv} can be used to transmit data that is not
@c meant to be shown to the remote party as plain text. The OTR protocol
@c allocates type 0 for padding, and this procedure automatically pads
@c messages with up to 7 bytes, to disguise message lengths. Types 1-7
@c are used by the SMP authentication protocol. Type 1 is used to tell
@c the remote party that your side is closing down the OTR connection.
@end deffn

@deffn Procedure otr-authenticate! state secret [question]
Initiate or respond to an authentication request.
After calling this procedure you should use @code{otr-empty-queue!},
just like with @code{otr-send-encrypted!}.

The authentication protocol can be used to verify that both partyies
know the @var{secret} bytevector. The secret is never revealed over
the network and is not even transmitted in an encrypted form. The
protocol used is the Socialist Millionaires' Protocol (SMP), which is
based on a series of zero-knowledge proofs.
@cindex Socialist Millionaires' Protocol
@end deffn

@deffn Procedure otr-empty-queue! state
Returns and clears the event queue. The queue is a list of pairs where
the symbol in the @code{car} of the pair determines its meaning. These
are the possible types:

@itemize
@item
@t{(outgoing . }@emph{line}@t{)} -- The @code{cdr} is a string
that should be sent to the remote party.
@item
@t{(encrypted . }@emph{msg}@t{)} -- The @code{cdr} is a string
that contains a decrypted message that was sent by the remote party.
@item
@t{(unencrypted . }@emph{msg}@t{)} -- The @code{cdr} is a string that
was sent @emph{unencrypted} by the remote party. This happens when a
whitespace-tagged message is received.
@item
@t{(session-established . }@emph{whence}@t{)} -- A session has been
established with the remote party. It is now safe to call
@code{otr-state-their-dsa-key}, @code{otr-state-secure-session-id},
@code{otr-send-encrypted!} and @code{otr-authenticate!}. The
@code{cdr} is the symbol @code{from-there} if the session was
initiated by the remote party. Otherwise it is @code{from-here}.
@item
@t{(session-finished . }@emph{whom}@t{)} -- The session is now
finished and no new messages can be sent over it. The @code{cdr} is
either the symbol @code{by-them} or @code{by-us}. @emph{Note}: there
is currently no way to finish the session from the local side, so
@code{by-us} is not used yet.
@item
@t{(authentication . expecting-secret)} -- The remote party has
started the authentication protocol and now expects you to
call @code{otr-authenticate!}.
@item
@t{(authentication . #t)} -- The authentication protocol has
succeeded and both parties had the same secret.
@item
@t{(authentication . #f)} -- The authentication protocol has
failed. The secrets were not identical.
@item
@t{(authentication . aborted-by-them)} -- The remote party
has aborted the authentication protocol.
@item
@t{(authentication . aborted-by-us)} -- The local party has
encountered an error and therefore aborted the authentication
protocol.
@item
@t{(they-revealed . }@emph{k}@t{)} -- The remote party revealed an old
signing key. This is a normal part of the protocol and the key is sent
unencrypted to ensure the deniability property. You might like to
reveal the key somehow yourself in case you're tunneling OTR over an
encrypted protocol.
@item
@t{(we-revealed . }@emph{k}@t{)} -- The local party has revealed an
old signing key. @emph{Note}: currently not used.
@item
@t{(undecipherable-message . #f)} -- An encrypted message was
received, but it was not possible to decrypt it. This might mean
e.g.@: that the remote and local parties have different sessions or
that a message was sent out of order.
@item
@t{(remote-error . }@emph{msg}@t{)} -- The remote party encountered a
protocol error and sent a plaintext error message (probably in
English).
@item
@t{(local-error . }@emph{con}@t{)} -- There was an exception raised
during processing of a message. The @code{cdr} is the condition object.
@item
@t{(symmetric-key-request . }@emph{@t{(}@emph{protocol}@t{ . }@emph{data}@t{)}}@t{)}
 -- The remote party has requested that the extra symmetric
key be used to communicate in some out-of-band protocol. See
@code{otr-send-symmetric-key-request!}. New for Industria 1.5.
@end itemize

For forward-compatibility you should ignore any pair with an unknown
@code{car}. Most messages are quite safe to ignore if you don't want
to handle them.
@end deffn

@deffn Procedure otr-state-their-dsa-key state
Returns the remote party's public DSA key. This should be used to
verify the remote party's identity. If the SMP authentication protocol
succeeds you can remember the hash of the key for the next session.
The user could also verify the key's hash by cell phone telephone or
something.
@end deffn

@deffn Procedure otr-state-our-dsa-key state
Returns the local party's private DSA key. This is useful when the
user is on the phone with the remote party. First convert it to a
public key with @code{dsa-private->public} and then hash it with
@code{otr-hash-public-key}.
@end deffn

@deffn Procedure otr-hash-public-key public-dsa-key
Hashes a public DSA key and formats it so that it can be shown to the
OTR user.
@end deffn

@deffn Procedure otr-state-secure-session-id state
Returns the @dfn{secure session ID} associated with the OTR state.
@end deffn

@deffn Procedure otr-format-session-id id
Formats a secure session ID in the format that is recommended when
the ID should be shown to the OTR user.

The first part of the ID should be shown in bold if the session was
initiated by the local party. Otherwise the second part should be bold.
@end deffn

@deffn Procedure otr-state-version state
The OTR protocol version used by the state. This is either the integer
@code{2} or the integer @code{3}. New for Industria 1.5.
@end deffn

@deffn Procedure otr-state-mss state
Returns the current maximum segment size of the OTR state.
@end deffn

@deffn Procedure otr-state-mss-set! state int
Sets @var{int} as the maximum segment size of the OTR state.
@end deffn

OTR protocol version 3 defines an extra symmetric key.

@deffn Procedure otr-send-symmetric-key-request! state protocol data
This sends a message to the remote party that requests that it uses
the extra symmetric key for some out-of-band protocol.

The remote party may ignore this request if the OTR protocol version
(as returned by @code{otr-state-version}) is not at least 3.

The @var{protocol} parameter is an unsigned 32-bit integer that
indicates what the key should be used for. At the time this manual is
written there are no defined uses. One might expect a list of uses to
appear in the protocol documentation at
@url{http://www.cypherpunks.ca/otr/}.

The @var{data} parameter is a bytevector containing protocol-dependent
data.
@end deffn

@deffn Procedure otr-state-symmetric-key state
This returns the extra symmetric key in the form of a 256-bit bytevector.
@end deffn

@deffn Procedure otr-tag whitespace? versions
Constructs a string that may be sent to a remote party as a request to
start an OTR session. New for Industria 1.5.

If @var{whitespace?} is true then a whitespace tag will be made. This
tag may be appended to a normal message sent by the user. If the
recipient's client supports OTR it may start a session, but if it does
not support OTR then hopefully it will not show the whitespaces.

The @var{versions} argument specifies which OTR protocol versions
should be present in the tag. This can either be a list of version
numbers or the symbol @code{all}.
@end deffn

@deffn Procedure otr-state-our-instance-tag state
This returns the local instance tag. It is new for Industria 1.5.

It is intended for instance tags to be persistent across client
restarts. If the local party crashes then the remote party may still
have an OTR session established. If the local client were then to
change its instance tag on restart it would not receive any messages
from the remote party and would not send error messages. To the remote
party it would look like they were being ignored.
@end deffn

Isn't this the most boring manual you've ever read?

@noindent
Version history:
@itemize
@item
Industria 1.5 introduced support for protocol version 3. This new
version of the protocol uses instance tags, which are used to
distinguish between different OTR sessions. This fixes a problem with
chat networks that allow multiple logins. The new version also defines
an extra symmetrical key that can be used by out-of-band protocols.
@end itemize
