From interrupt80h at gmail.com Sat Apr 9 15:51:18 2011 From: interrupt80h at gmail.com (interrupt80h at gmail.com) Date: Sat, 9 Apr 2011 12:51:18 -0700 Subject: [OTR-dev] Using otrl_privkey_verify() Message-ID: How does one make use of otrl_privkey_sign() and otrl_privkey_verify()? There are no docs that I could find, and the verify prototype is rather mysterious to me. Thanks! From kb at pentabarf.de Sun Apr 10 07:34:14 2011 From: kb at pentabarf.de (Kjell Braden) Date: Sun, 10 Apr 2011 13:34:14 +0200 Subject: [OTR-dev] Using otrl_privkey_verify() In-Reply-To: References: Message-ID: <4DA195B6.2020104@pentabarf.de> On 09.04.2011 21:51, interrupt80h at gmail.com wrote: > How does one make use of otrl_privkey_sign() and > otrl_privkey_verify()? There are no docs that I could find, and the > verify prototype is rather mysterious to me. > > Thanks! Hi, as far as I know, these methods are only used by the lib itself to verify the signatures in the Reveal Signature / Signature Messages. You won't need them in your application. HTH -- Kjell -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From kb at pentabarf.de Sun Apr 10 07:35:25 2011 From: kb at pentabarf.de (Kjell Braden) Date: Sun, 10 Apr 2011 13:35:25 +0200 Subject: [OTR-dev] Issues with libgcrypt 1.5 Message-ID: <4DA195FD.20409@pentabarf.de> (sorry if this appears twice, I wasn't subscribed with the correct email address) Hi, FYI: libgcrypt-1.5.0_beta1 seems to throw GPG_ERR_INV_LENGTH errors when encrypting/decrypting messages using AES-CTR when their length is not a multiple of the block size (16?). This makes libotr unusable with that version. -- Kjell From ian at cypherpunks.ca Sun Apr 10 10:58:57 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Sun, 10 Apr 2011 10:58:57 -0400 Subject: [OTR-dev] Issues with libgcrypt 1.5 In-Reply-To: <4DA195FD.20409@pentabarf.de> References: <4DA195FD.20409@pentabarf.de> Message-ID: <20110410145857.GA2073@yoink.cs.uwaterloo.ca> Werner Koch wrote: > On Wed, 9 Mar 2011 18:19, arfrever.fta [at] gmail said: > > I have added Libgcrypt 1.5.0-beta1 to Gentoo's main repository on > > 2011-02-23. > > Until now, only problem [1] with libotr [2] has been reported. > > Could you check if it is a bug in Libgcrypt 1.5.0-beta1 or in libotr? > > Well, I need a bit more of info. Which function returns with "invalid > length"? I need a small test case (w/o any gentoo or KDE specific > stuff). and Kjell Branded (on the otr-dev list wrote): > FYI: libgcrypt-1.5.0_beta1 seems to throw GPG_ERR_INV_LENGTH errors when > encrypting/decrypting messages using AES-CTR when their length is not a > multiple of the block size (16?). This makes libotr unusable with that > version. Werner, would it be possible to revert libgcrypt's behaviour to internally handle a truncated final block for AES-CTR mode? Thanks, - Ian From ian at cypherpunks.ca Sun Apr 10 16:40:35 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Sun, 10 Apr 2011 16:40:35 -0400 Subject: [OTR-dev] purpose of hash commitment in OTR authenticated key exchange In-Reply-To: References: <20110316212958.GY2058@yoink.cs.uwaterloo.ca> Message-ID: <20110410204035.GJ2073@yoink.cs.uwaterloo.ca> On Thu, Mar 17, 2011 at 10:58:09AM +0100, Stefan Sch?nleitner wrote: > While I understand the purpose of the key a2 (which is to authenticate > Alice's messages that are sent over an insecure channel), I'm not exactly > sure what the purpose of a1 is. > Wouldn't the exchange be the same if Alice used an unkeyed hash function > like SHA256 to sign the DH public keys and her long-term public key (i.e. > she would sign SHA256(g^x,g^y,v_A)) ? > Sure, the whole idea of SIGMA is to SIGn and MAc, but apart from that I do > not see the reason why in this case a MAC instead of a reguar unkeyed hash > function is used. > IMHO in this case it doesn't bring any additional security, right ? If you just did the above (with SHA256), there's no evidence that Alice has actually computed (or was able to compute) the shared secret g^{xy}. In such a case, there are identity misbinding attacks that are possible, where Alice makes Bob think he's talking to her, when he's really taking to Carol. - Ian From ian at cypherpunks.ca Mon Apr 11 07:48:36 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Mon, 11 Apr 2011 07:48:36 -0400 Subject: [OTR-dev] Issues with libgcrypt 1.5 In-Reply-To: <87mxjx5gkl.fsf@vigenere.g10code.de> References: <4DA195FD.20409@pentabarf.de> <20110410145857.GA2073@yoink.cs.uwaterloo.ca> <87mxjx5gkl.fsf@vigenere.g10code.de> Message-ID: <20110411114836.GA30160@thunk.cs.uwaterloo.ca> On Mon, Apr 11, 2011 at 10:37:46AM +0200, Werner Koch wrote: > On Sun, 10 Apr 2011 16:58, ian at cypherpunks.ca said: > > > Werner, would it be possible to revert libgcrypt's behaviour to > > internally handle a truncated final block for AES-CTR mode? > > Can you pelase specifiy the behaviour you want? It is still time to > loose this check. In 1.4, if the plaintext was not a multiple of the block size, the last encrypted counter block was simply truncated to the appropriate length, which seems like the correct behaviour to me. (And indeed, is what the libotr library expects.) Ideally, CTR mode would operate like a stream cipher whose keystream was E(c) || E(c+1) || E(c+2) || ... . That would mean stashing away the "truncated" part above for use at the start of the next encryption. I don't know whether 1.4 did that or not; I didn't try encrypting twice between resetting the key/counter. So it would seem to be fairly easy to just revert the 1.4 behaviour for now, and if that's not the "stream cipher" behaviour, maybe see if that can get into 1.5 as well? Thanks, - Ian From ian at cypherpunks.ca Mon Apr 11 13:03:02 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Mon, 11 Apr 2011 13:03:02 -0400 Subject: [OTR-dev] Issues with libgcrypt 1.5 In-Reply-To: <8739lo6bi7.fsf@vigenere.g10code.de> References: <4DA195FD.20409@pentabarf.de> <20110410145857.GA2073@yoink.cs.uwaterloo.ca> <87mxjx5gkl.fsf@vigenere.g10code.de> <20110411114836.GA30160@thunk.cs.uwaterloo.ca> <8739lo6bi7.fsf@vigenere.g10code.de> Message-ID: <20110411170302.GP30160@thunk.cs.uwaterloo.ca> On Mon, Apr 11, 2011 at 05:41:52PM +0200, Werner Koch wrote: > On Mon, 11 Apr 2011 13:48, ian at cypherpunks.ca said: > > > So it would seem to be fairly easy to just revert the 1.4 behaviour for > > now, and if that's not the "stream cipher" behaviour, maybe see if that > > can get into 1.5 as well? > > (Maybe I can do it without an extra block layer.) > > Do you have short test messages, I can use of the regression tests (from > libgcrypt 1.4)? Take any message of length, say, 45. Init the key and counter, and encrypt. Then start again with the same message, key, and counter. Encrypt the first x bytes, and then the remaining 45-x (both in place). You should get the same answer. If you do this with x = 0,1,7,8,9,15,16,17,22, that should be a good set of test cases, I think. Thanks, - Ian From ian at cypherpunks.ca Mon Apr 11 14:20:23 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Mon, 11 Apr 2011 14:20:23 -0400 Subject: [OTR-dev] Issues with libgcrypt 1.5 In-Reply-To: <87y63g4ruc.fsf@vigenere.g10code.de> References: <4DA195FD.20409@pentabarf.de> <20110410145857.GA2073@yoink.cs.uwaterloo.ca> <87mxjx5gkl.fsf@vigenere.g10code.de> <20110411114836.GA30160@thunk.cs.uwaterloo.ca> <8739lo6bi7.fsf@vigenere.g10code.de> <20110411170302.GP30160@thunk.cs.uwaterloo.ca> <87y63g4ruc.fsf@vigenere.g10code.de> Message-ID: <20110411182023.GX30160@thunk.cs.uwaterloo.ca> On Mon, Apr 11, 2011 at 07:31:55PM +0200, Werner Koch wrote: > On Mon, 11 Apr 2011 19:03, ian at cypherpunks.ca said: > > > If you do this with x = 0,1,7,8,9,15,16,17,22, that should be a good set > > of test cases, I think. > > I was more thinking of a testcase you use in libotr. Anyway, I added a > simple truncation tests which was easy to add to the existsing tests. > Find attached a patch. Excellent, thanks! I'll have Rob test OTR with this patch, and I'll let you know whether it all works now. - Ian > >From 3c18377a55085faf4df745034056bac53565effa Mon Sep 17 00:00:00 2001 > From: Werner Koch > Date: Mon, 11 Apr 2011 19:21:47 +0200 > Subject: [PATCH] Allow for truncation in CTR mode. > > This re-enables the behaviour of Libgcrypt 1.4. Such truncation is > used by libotr and the current error-ed out here. The bug was > introduced due to a rewrite of the function and the undocumented > feature of truncating OTR data. > --- > cipher/ChangeLog | 5 ++ > cipher/cipher.c | 12 ++-- > tests/ChangeLog | 6 ++ > tests/basic.c | 136 ++++++++++++++++++++++++++++++++++++++++++----------- > 4 files changed, 124 insertions(+), 35 deletions(-) > > diff --git a/cipher/ChangeLog b/cipher/ChangeLog > index df27bab..4cde857 100644 > --- a/cipher/ChangeLog > +++ b/cipher/ChangeLog > @@ -1,3 +1,8 @@ > +2011-04-11 Werner Koch > + > + * cipher.c (do_ctr_encrypt): Allow arbitrary length inputs to > + match the 1.4 behaviour. > + > 2011-04-04 Werner Koch > > * ecc.c (compute_keygrip): Release L1 while parsing "curve". > diff --git a/cipher/cipher.c b/cipher/cipher.c > index a2f8bb9..e5bb2e0 100644 > --- a/cipher/cipher.c > +++ b/cipher/cipher.c > @@ -1453,22 +1453,22 @@ do_ctr_encrypt (gcry_cipher_hd_t c, > unsigned int blocksize = c->cipher->blocksize; > unsigned int nblocks; > > - /* FIXME: This code does only work on complete blocks. */ > - > if (outbuflen < inbuflen) > return GPG_ERR_BUFFER_TOO_SHORT; > > - if ((inbuflen % blocksize)) > - return GPG_ERR_INV_LENGTH; > - > + /* Use a bulk method if available. */ > nblocks = inbuflen / blocksize; > if (nblocks && c->bulk.ctr_enc) > { > c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks); > inbuf += nblocks * blocksize; > outbuf += nblocks * blocksize; > + inbuflen -= nblocks * blocksize; > } > - else > + > + /* If we don't have a bulk method use the standard method. We also > + use this method for the a remaining partial block. */ > + if (inbuflen) > { > unsigned char tmp[MAX_BLOCKSIZE]; > > diff --git a/tests/ChangeLog b/tests/ChangeLog > index 0f5918a..3793149 100644 > --- a/tests/ChangeLog > +++ b/tests/ChangeLog > @@ -1,3 +1,9 @@ > +2011-04-11 Werner Koch > + > + * basic.c (mismatch): New. > + (check_ctr_cipher): Remove length error code checks. Add > + truncation checks. > + > 2011-04-04 Werner Koch > > * keygrip.c (main): Add option --repetitions. > diff --git a/tests/basic.c b/tests/basic.c > index 185091e..a20e731 100644 > --- a/tests/basic.c > +++ b/tests/basic.c > @@ -69,6 +69,22 @@ fail (const char *format, ...) > } > > static void > +mismatch (const void *expected, size_t expectedlen, > + const void *computed, size_t computedlen) > +{ > + const unsigned char *p; > + > + fprintf (stderr, "expected:"); > + for (p = expected; expectedlen; p++, expectedlen--) > + fprintf (stderr, " %02x", *p); > + fprintf (stderr, "\ncomputed:"); > + for (p = computed; computedlen; p++, computedlen--) > + fprintf (stderr, " %02x", *p); > + fprintf (stderr, "\n"); > +} > + > + > +static void > die (const char *format, ...) > { > va_list arg_ptr; > @@ -349,8 +365,7 @@ check_ctr_cipher (void) > unsigned char plaintext[MAX_DATA_LEN]; > int inlen; > char out[MAX_DATA_LEN]; > - } > - data[MAX_DATA_LEN]; > + } data[5]; > } tv[] = > { > /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ > @@ -369,6 +384,8 @@ check_ctr_cipher (void) > { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", > 16, > "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, > + > + { "", 0, "" } > } > }, > { GCRY_CIPHER_AES192, > @@ -387,6 +404,7 @@ check_ctr_cipher (void) > { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", > 16, > "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" }, > + { "", 0, "" } > } > }, > { GCRY_CIPHER_AES256, > @@ -404,7 +422,80 @@ check_ctr_cipher (void) > "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" }, > { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", > 16, > - "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" } > + "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }, > + { "", 0, "" } > + } > + }, > + /* Some truncation tests. With a truncated second block and > + also with a single truncated block. */ > + { GCRY_CIPHER_AES, > + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", > + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", > + {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", > + 16, > + "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, > + {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", > + 15, > + "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, > + {"", 0, "" } > + } > + }, > + { GCRY_CIPHER_AES, > + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", > + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", > + {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", > + 16, > + "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, > + {"\xae", > + 1, > + "\x98" }, > + {"", 0, "" } > + } > + }, > + { GCRY_CIPHER_AES, > + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", > + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", > + {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17", > + 15, > + "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6" }, > + {"", 0, "" } > + } > + }, > + { GCRY_CIPHER_AES, > + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", > + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", > + {{"\x6b", > + 1, > + "\x87" }, > + {"", 0, "" } > + } > + }, > +#if USE_CAST5 > + /* A selfmade test vector using an 64 bit block cipher. */ > + { GCRY_CIPHER_CAST5, > + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", > + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8", > + {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", > + 16, > + "\xe8\xa7\xac\x68\xca\xca\xa0\x20\x10\xcb\x1b\xcc\x79\x2c\xc4\x48" }, > + {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c", > + 8, > + "\x16\xe8\x72\x77\xb0\x98\x29\x68" }, > + {"\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", > + 8, > + "\x9a\xb3\xa8\x03\x3b\xb4\x14\xba" }, > + {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\xa1\x00", > + 10, > + "\x31\x5e\xd3\xfb\x1b\x8d\xd1\xf9\xb0\x83" }, > + { "", 0, "" } > + } > + }, > +#endif /*USE_CAST5*/ > + { 0, > + "", > + "", > + { > + {"", 0, "" } > } > } > }; > @@ -417,6 +508,9 @@ check_ctr_cipher (void) > fprintf (stderr, " Starting CTR cipher checks.\n"); > for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) > { > + if (!tv[i].algo) > + continue; > + > err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); > if (!err) > err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); > @@ -485,7 +579,11 @@ check_ctr_cipher (void) > } > > if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) > - fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); > + { > + fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); > + mismatch (tv[i].data[j].out, tv[i].data[j].inlen, > + out, tv[i].data[j].inlen); > + } > > err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); > if (err) > @@ -498,7 +596,11 @@ check_ctr_cipher (void) > } > > if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) > - fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); > + { > + fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); > + mismatch (tv[i].data[j].plaintext, tv[i].data[j].inlen, > + out, tv[i].data[j].inlen); > + } > > } > > @@ -509,18 +611,6 @@ check_ctr_cipher (void) > if (err) > fail ("aes-ctr, encryption failed for valid input"); > > - err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, > - "1234567890123456", 15); > - if (gpg_err_code (err) != GPG_ERR_INV_LENGTH) > - fail ("aes-ctr, too short input returned wrong error: %s\n", > - gpg_strerror (err)); > - > - err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, > - "12345678901234567", 17); > - if (gpg_err_code (err) != GPG_ERR_INV_LENGTH) > - fail ("aes-ctr, too long input returned wrong error: %s\n", > - gpg_strerror (err)); > - > err = gcry_cipher_encrypt (hde, out, 15, > "1234567890123456", 16); > if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) > @@ -545,18 +635,6 @@ check_ctr_cipher (void) > if (err) > fail ("aes-ctr, decryption failed for valid input"); > > - err = gcry_cipher_decrypt (hde, out, MAX_DATA_LEN, > - "1234567890123456", 15); > - if (gpg_err_code (err) != GPG_ERR_INV_LENGTH) > - fail ("aes-ctr, too short input returned wrong error: %s\n", > - gpg_strerror (err)); > - > - err = gcry_cipher_decrypt (hde, out, MAX_DATA_LEN, > - "12345678901234567", 17); > - if (gpg_err_code (err) != GPG_ERR_INV_LENGTH) > - fail ("aes-ctr, too long input returned wrong error: %s\n", > - gpg_strerror (err)); > - > err = gcry_cipher_decrypt (hde, out, 15, > "1234567890123456", 16); > if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) > -- > 1.7.2.3 > From ian at cypherpunks.ca Tue Apr 12 18:00:11 2011 From: ian at cypherpunks.ca (Ian Goldberg) Date: Tue, 12 Apr 2011 18:00:11 -0400 Subject: [OTR-dev] Issues with libgcrypt 1.5 In-Reply-To: <87tye44lpz.fsf@vigenere.g10code.de> References: <4DA195FD.20409@pentabarf.de> <20110410145857.GA2073@yoink.cs.uwaterloo.ca> <87mxjx5gkl.fsf@vigenere.g10code.de> <20110411114836.GA30160@thunk.cs.uwaterloo.ca> <8739lo6bi7.fsf@vigenere.g10code.de> <20110411170302.GP30160@thunk.cs.uwaterloo.ca> <87y63g4ruc.fsf@vigenere.g10code.de> <20110411182023.GX30160@thunk.cs.uwaterloo.ca> <87tye44lpz.fsf@vigenere.g10code.de> Message-ID: <20110412220011.GD2073@yoink.cs.uwaterloo.ca> On Mon, Apr 11, 2011 at 09:44:08PM +0200, Werner Koch wrote: > On Mon, 11 Apr 2011 20:20, ian at cypherpunks.ca said: > > > Excellent, thanks! I'll have Rob test OTR with this patch, and I'll let > > you know whether it all works now. > > Meanwhile I added the real stream mode for CTR (like with CFB). All > pushed to the repo; you may also use the attached patch. Rob confirms that OTR works again with current git. Thanks! - Ian From donny.viszneki at gmail.com Fri Apr 29 12:41:22 2011 From: donny.viszneki at gmail.com (Donny Viszneki) Date: Fri, 29 Apr 2011 12:41:22 -0400 Subject: [OTR-dev] human-readable message hints for session life cycle events Message-ID: Hi all, I love OTR, but occasionally I have to tell someone "no otr!" But sometimes I find out that my friend is not messaging me, but rather has ended our OTR session. Perhaps it can be worked into the existing protocol, or just put into a checklist somewhere for a future revision of the protocol, to tell a user that an OTR message is ending the OTR session. Perhaps I have not thought it through enough and there is a reason to disguise this message, but if I recall the details of OTR's design goals, this should not be the case. Is there any way I could tell that now if I didn't have an OTR client? Thanks for this great software :) -- http://codebad.com/