[Pkg-privacy-commits] [libotr] 19/225: * src/auth.h: * src/auth.c: * src/message.c: Ensure version 2 AKEs are always done with fresh D-H parameters.
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:44:46 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository libotr.
commit 2248483f4877893c2b975a32ddc561771066677d
Author: cypherpunk <cypherpunk>
Date: Thu Oct 27 16:01:04 2005 +0000
* src/auth.h:
* src/auth.c:
* src/message.c: Ensure version 2 AKEs are always done with
fresh D-H parameters.
* src/proto.h:
* src/proto.c:
* src/message.c: Add a "flags" field to the version 2 Data
Message, which can indicate that the Data Message should be
ignored if unreadable (as opposed to displaying an error).
* toolkit/parse.h:
* toolkit/parse.c:
* toolkit/otr_parse.c:
* toolkit/otr_remac.c: Deal with the new kind of Data Message.
---
ChangeLog | 18 +++++++++++
src/auth.c | 47 +++++++++--------------------
src/auth.h | 19 +++++-------
src/message.c | 56 ++++++++++++++++++++--------------
src/proto.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++----
src/proto.h | 15 ++++++---
src/tests.c | 18 ++++++++++-
toolkit/otr_parse.c | 3 ++
toolkit/otr_remac.c | 28 ++++++++++-------
toolkit/parse.c | 36 +++++++++++++++++-----
toolkit/parse.h | 9 +++---
11 files changed, 235 insertions(+), 101 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6c6f8ac..cfa462a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2005-10-27
+
+ * src/auth.h:
+ * src/auth.c:
+ * src/message.c: Ensure version 2 AKEs are always done with
+ fresh D-H parameters.
+
+ * src/proto.h:
+ * src/proto.c:
+ * src/message.c: Add a "flags" field to the version 2 Data
+ Message, which can indicate that the Data Message should be
+ ignored if unreadable (as opposed to displaying an error).
+
+ * toolkit/parse.h:
+ * toolkit/parse.c:
+ * toolkit/otr_parse.c:
+ * toolkit/otr_remac.c: Deal with the new kind of Data Message.
+
2005-10-19
* src/context.h:
diff --git a/src/auth.c b/src/auth.c
index 067beb7..f40f018 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -94,14 +94,11 @@ void otrl_auth_clear(OtrlAuthInfo *auth)
}
/*
- * Start a fresh AKE (version 2) using the given OtrlAuthInfo. If
- * our_dh is NULL, generate a fresh DH keypair to use. Otherwise, use a
- * copy of the one passed (with the given keyid). If no error is
- * returned, the message to transmit will be contained in
- * auth->lastauthmsg.
+ * Start a fresh AKE (version 2) using the given OtrlAuthInfo. Generate
+ * a fresh DH keypair to use. If no error is returned, the message to
+ * transmit will be contained in auth->lastauthmsg.
*/
-gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth, DH_keypair *our_dh,
- unsigned int our_keyid)
+gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth)
{
gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR);
const enum gcry_mpi_format format = GCRYMPI_FMT_USG;
@@ -115,14 +112,8 @@ gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth, DH_keypair *our_dh,
otrl_auth_clear(auth);
auth->initiated = 1;
- /* Import the given DH keypair, or else create a fresh one */
- if (our_dh) {
- otrl_dh_keypair_copy(&(auth->our_dh), our_dh);
- auth->our_keyid = our_keyid;
- } else {
- otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
- auth->our_keyid = 1;
- }
+ otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
+ auth->our_keyid = 1;
/* Pick an encryption key */
gcry_randomize(auth->r, 16, GCRY_STRONG_RANDOM);
@@ -243,11 +234,11 @@ memerr:
/*
* Handle an incoming D-H Commit Message. If no error is returned, the
- * message to send will be left in auth->lastauthmsg. If non-NULL, use
- * a copy of the given D-H keypair, with the given keyid.
+ * message to send will be left in auth->lastauthmsg. Generate a fresh
+ * keypair to use.
*/
-gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, const char *commitmsg,
- DH_keypair *our_dh, unsigned int our_keyid)
+gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth,
+ const char *commitmsg)
{
gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR);
unsigned char *buf = NULL, *bufp = NULL, *encbuf = NULL;
@@ -293,13 +284,8 @@ gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, const char *commitmsg,
/* Store the incoming information */
otrl_auth_clear(auth);
- if (our_dh) {
- otrl_dh_keypair_copy(&(auth->our_dh), our_dh);
- auth->our_keyid = our_keyid;
- } else {
- otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
- auth->our_keyid = 1;
- }
+ otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
+ auth->our_keyid = 1;
auth->encgx = encbuf;
encbuf = NULL;
auth->encgx_len = enclen;
@@ -323,13 +309,8 @@ gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, const char *commitmsg,
} else {
/* Ours loses. Use the incoming parameters instead. */
otrl_auth_clear(auth);
- if (our_dh) {
- otrl_dh_keypair_copy(&(auth->our_dh), our_dh);
- auth->our_keyid = our_keyid;
- } else {
- otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
- auth->our_keyid = 1;
- }
+ otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh));
+ auth->our_keyid = 1;
auth->encgx = encbuf;
encbuf = NULL;
auth->encgx_len = enclen;
diff --git a/src/auth.h b/src/auth.h
index 08744c0..8fa936c 100644
--- a/src/auth.h
+++ b/src/auth.h
@@ -85,22 +85,19 @@ void otrl_auth_new(OtrlAuthInfo *auth);
void otrl_auth_clear(OtrlAuthInfo *auth);
/*
- * Start a fresh AKE (version 2) using the given OtrlAuthInfo. If
- * our_dh is NULL, generate a fresh DH keypair to use. Otherwise, use a
- * copy of the one passed (with the given keyid). If no error is
- * returned, the message to transmit will be contained in
- * auth->lastauthmsg.
+ * Start a fresh AKE (version 2) using the given OtrlAuthInfo. Generate
+ * a fresh DH keypair to use. If no error is returned, the message to
+ * transmit will be contained in auth->lastauthmsg.
*/
-gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth, DH_keypair *our_dh,
- unsigned int our_keyid);
+gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth);
/*
* Handle an incoming D-H Commit Message. If no error is returned, the
- * message to send will be left in auth->lastauthmsg. If non-NULL, use
- * a copy of the given D-H keypair, with the given keyid.
+ * message to send will be left in auth->lastauthmsg. Generate a fresh
+ * keypair to use.
*/
-gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, const char *commitmsg,
- DH_keypair *our_dh, unsigned int our_keyid);
+gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth,
+ const char *commitmsg);
/*
* Handle an incoming D-H Key Message. If no error is returned, and
diff --git a/src/message.c b/src/message.c
index 8fa34b5..7b07756 100644
--- a/src/message.c
+++ b/src/message.c
@@ -188,7 +188,8 @@ gcry_error_t otrl_message_sending(OtrlUserState us,
break;
case OTRL_MSGSTATE_ENCRYPTED:
/* Create the new, encrypted message */
- err = otrl_proto_create_data(&msgtosend, context, message, tlvs);
+ err = otrl_proto_create_data(&msgtosend, context, message, tlvs,
+ 0);
if (!err) {
context->lastsent = time(NULL);
*messagep = msgtosend;
@@ -301,6 +302,7 @@ static gcry_error_t go_encrypted(const OtrlAuthInfo *auth, void *asdata)
gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR);
Fingerprint *found_print = NULL;
int fprint_added = 0;
+ OtrlMessageState oldstate = edata->context->msgstate;
/* See if we're talking to ourselves */
if (!gcry_mpi_cmp(auth->their_pub, auth->our_dh.pub)) {
@@ -412,8 +414,15 @@ static gcry_error_t go_encrypted(const OtrlAuthInfo *auth, void *asdata)
if (edata->ops->update_context_list) {
edata->ops->update_context_list(edata->opdata);
}
- if (edata->ops->gone_secure) {
- edata->ops->gone_secure(edata->opdata, edata->context);
+ if (oldstate == OTRL_MSGSTATE_ENCRYPTED) {
+ if (edata->ops->still_secure) {
+ edata->ops->still_secure(edata->opdata, edata->context,
+ edata->context->auth.initiated);
+ }
+ } else {
+ if (edata->ops->gone_secure) {
+ edata->ops->gone_secure(edata->opdata, edata->context);
+ }
}
edata->gone_encrypted = 1;
@@ -438,7 +447,7 @@ static void maybe_resend(EncrData *edata)
/* Re-encrypt the message with the new keys */
err = otrl_proto_create_data(&resendmsg,
- edata->context, edata->context->lastmessage, NULL);
+ edata->context, edata->context->lastmessage, NULL, 0);
if (!err) {
const char *format = "<b>The last message "
"to %s was resent.</b>";
@@ -608,8 +617,7 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
/* Find the best version of OTR that we both speak */
switch(otrl_proto_query_bestversion(message, policy)) {
case 2:
- err = otrl_auth_start_v2(&(context->auth), our_dh,
- our_keyid);
+ err = otrl_auth_start_v2(&(context->auth));
send_or_error_auth(ops, opdata, err, context);
break;
case 1:
@@ -641,18 +649,7 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
case OTRL_MSGTYPE_DH_COMMIT:
if ((policy & OTRL_POLICY_ALLOW_V2)) {
- /* See if we should use an existing DH keypair, or generate
- * a fresh one. */
- if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
- our_dh = &(context->our_old_dh_key);
- our_keyid = context->our_keyid - 1;
- } else {
- our_dh = NULL;
- our_keyid = 0;
- }
-
- err = otrl_auth_handle_commit(&(context->auth), message,
- our_dh, our_keyid);
+ err = otrl_auth_handle_commit(&(context->auth), message);
send_or_error_auth(ops, opdata, err, context);
}
@@ -771,8 +768,17 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
char *plaintext;
char *buf;
char *format;
+ unsigned char flags;
case OTRL_MSGSTATE_PLAINTEXT:
case OTRL_MSGSTATE_FINISHED:
+ /* See if we're supposed to ignore this message in
+ * the event it's unreadable. */
+ err = otrl_proto_data_read_flags(message, &flags);
+ if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) {
+ edata.ignore_message = 1;
+ break;
+ }
+
/* Don't use g_strdup_printf here, because someone
* (not us) is going to free() the *newmessagep pointer,
* not g_free() it. */
@@ -813,10 +819,14 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
case OTRL_MSGSTATE_ENCRYPTED:
err = otrl_proto_accept_data(&plaintext, &tlvs, context,
- message);
+ message, &flags);
if (err) {
int is_conflict =
(gpg_err_code(err) == GPG_ERR_CONFLICT);
+ if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) {
+ edata.ignore_message = 1;
+ break;
+ }
format = is_conflict ? "We received an unreadable "
"encrypted messahe from %s." :
"We received a malformed data message from %s.";
@@ -876,7 +886,8 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
/* Create the heartbeat message */
err = otrl_proto_create_data(&heartbeat,
- context, "", NULL);
+ context, "", NULL,
+ OTRL_MSGFLAGS_IGNORE_UNREADABLE);
if (!err) {
/* Send it, and log a debug message */
if (ops->inject_message) {
@@ -974,7 +985,7 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
&& (policy & OTRL_POLICY_WHITESPACE_START_AKE)) {
switch(bestversion) {
case 2:
- err = otrl_auth_start_v2(&(context->auth), NULL, 0);
+ err = otrl_auth_start_v2(&(context->auth));
send_or_error_auth(ops, opdata, err, context);
break;
case 1:
@@ -1088,7 +1099,8 @@ void otrl_message_disconnect(OtrlUserState us, const OtrlMessageAppOps *ops,
gcry_error_t err;
OtrlTLV *tlv = otrl_tlv_new(OTRL_TLV_DISCONNECTED, 0, NULL);
- err = otrl_proto_create_data(&encmsg, context, "", tlv);
+ err = otrl_proto_create_data(&encmsg, context, "", tlv,
+ OTRL_MSGFLAGS_IGNORE_UNREADABLE);
if (!err) {
ops->inject_message(opdata, accountname, protocol,
username, encmsg);
diff --git a/src/proto.c b/src/proto.c
index 5055ba5..fdd2a99 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -336,6 +336,7 @@ OtrlMessageType otrl_proto_message_type(const char *message)
if (!strncmp(otrtag, "?OTR:AAIS", 9)) return OTRL_MSGTYPE_SIGNATURE;
if (!strncmp(otrtag, "?OTR:AAEK", 9)) return OTRL_MSGTYPE_V1_KEYEXCH;
if (!strncmp(otrtag, "?OTR:AAED", 9)) return OTRL_MSGTYPE_DATA;
+ if (!strncmp(otrtag, "?OTR:AAID", 9)) return OTRL_MSGTYPE_DATA;
if (!strncmp(otrtag, "?OTR Error:", 11)) return OTRL_MSGTYPE_ERROR;
return OTRL_MSGTYPE_UNKNOWN;
@@ -345,7 +346,7 @@ OtrlMessageType otrl_proto_message_type(const char *message)
* optional chain of TLVs. A newly-allocated string will be returned in
* *encmessagep. */
gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
- const char *msg, const OtrlTLV *tlvs)
+ const char *msg, const OtrlTLV *tlvs, unsigned char flags)
{
size_t justmsglen = strlen(msg);
size_t msglen = justmsglen + 1 + otrl_tlv_seriallen(tlvs);
@@ -362,6 +363,7 @@ gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
char *msgbuf = NULL;
enum gcry_mpi_format format = GCRYMPI_FMT_USG;
char *msgdup;
+ int version = context->protocol_version;
/* Make sure we're actually supposed to be able to encrypt */
if (context->msgstate != OTRL_MSGSTATE_ENCRYPTED ||
@@ -381,7 +383,8 @@ gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
/* Header, send keyid, recv keyid, counter, msg len, msg
* len of revealed mac keys, revealed mac keys, MAC */
- buflen = 3 + 4 + 4 + 8 + 4 + msglen + 4 + reveallen + 20;
+ buflen = 3 + (version == 2 ? 1 : 0) + 4 + 4 + 8 + 4 + msglen +
+ 4 + reveallen + 20;
gcry_mpi_print(format, NULL, 0, &pubkeylen, context->our_dh_key.pub);
buflen += pubkeylen + 4;
buf = malloc(buflen);
@@ -397,9 +400,17 @@ gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
otrl_tlv_serialize(msgbuf + justmsglen + 1, tlvs);
bufp = buf;
lenp = buflen;
- memmove(bufp, "\x00\x01\x03", 3); /* header */
+ if (version == 1) {
+ memmove(bufp, "\x00\x01\x03", 3); /* header */
+ } else {
+ memmove(bufp, "\x00\x02\x03", 3); /* header */
+ }
debug_data("Header", bufp, 3);
bufp += 3; lenp -= 3;
+ if (version == 2) {
+ bufp[0] = flags;
+ bufp += 1; lenp -= 1;
+ }
write_int(context->our_keyid-1); /* sender keyid */
debug_int("Sender keyid", bufp-4);
write_int(context->their_keyid); /* recipient keyid */
@@ -488,10 +499,66 @@ err:
return err;
}
+/* Extract the flags from an otherwise unreadable Data Message. */
+gcry_error_t otrl_proto_data_read_flags(const char *datamsg,
+ unsigned char *flagsp)
+{
+ char *otrtag, *endtag;
+ unsigned char *rawmsg = NULL;
+ unsigned char *bufp;
+ size_t msglen, rawlen, lenp;
+ unsigned char version;
+
+ if (flagsp) *flagsp = 0;
+ otrtag = strstr(datamsg, "?OTR:");
+ if (!otrtag) {
+ goto invval;
+ }
+ endtag = strchr(otrtag, '.');
+ if (endtag) {
+ msglen = endtag-otrtag;
+ } else {
+ msglen = strlen(otrtag);
+ }
+
+ /* Base64-decode the message */
+ rawlen = ((msglen-5) / 4) * 3; /* maximum possible */
+ rawmsg = malloc(rawlen);
+ if (!rawmsg && rawlen > 0) {
+ return gcry_error(GPG_ERR_ENOMEM);
+ }
+ rawlen = otrl_base64_decode(rawmsg, otrtag+5, msglen-5); /* actual size */
+
+ bufp = rawmsg;
+ lenp = rawlen;
+
+ require_len(3);
+ if (memcmp(bufp, "\x00\x01\x03", 3) && memcmp(bufp, "\x00\x02\x03", 3)) {
+ /* Invalid header */
+ goto invval;
+ }
+ version = bufp[1];
+ bufp += 3; lenp -= 3;
+
+ if (version == 2) {
+ require_len(1);
+ if (flagsp) *flagsp = bufp[0];
+ bufp += 1; lenp -= 1;
+ }
+
+ free(rawmsg);
+ return gcry_error(GPG_ERR_NO_ERROR);
+
+invval:
+ free(rawmsg);
+ return gcry_error(GPG_ERR_INV_VALUE);
+}
+
/* Accept an OTR Data Message in datamsg. Decrypt it and put the
- * plaintext into *plaintextp, and any TLVs into tlvsp. */
+ * plaintext into *plaintextp, and any TLVs into tlvsp. Put any
+ * received flags into *flagsp (if non-NULL). */
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
- ConnContext *context, const char *datamsg)
+ ConnContext *context, const char *datamsg, unsigned char *flagsp)
{
char *otrtag, *endtag;
gcry_error_t err;
@@ -507,9 +574,11 @@ gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
unsigned char *nul = NULL;
unsigned char givenmac[20];
DH_sesskeys *sess;
+ unsigned char version;
*plaintextp = NULL;
*tlvsp = NULL;
+ if (flagsp) *flagsp = 0;
otrtag = strstr(datamsg, "?OTR:");
if (!otrtag) {
goto invval;
@@ -535,12 +604,18 @@ gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
macstart = bufp;
require_len(3);
- if (memcmp(bufp, "\x00\x01\x03", 3)) {
+ if (memcmp(bufp, "\x00\x01\x03", 3) && memcmp(bufp, "\x00\x02\x03", 3)) {
/* Invalid header */
goto invval;
}
+ version = bufp[1];
bufp += 3; lenp -= 3;
+ if (version == 2) {
+ require_len(1);
+ if (flagsp) *flagsp = bufp[0];
+ bufp += 1; lenp -= 1;
+ }
read_int(sender_keyid);
read_int(recipient_keyid);
read_mpi(sender_next_y);
diff --git a/src/proto.h b/src/proto.h
index 03adecf..5fd2d3a 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -31,8 +31,8 @@
#define OTRL_MESSAGE_TAG_V1 " \t \t \t "
#define OTRL_MESSAGE_TAG_V2 " \t\t \t "
- /* This is the bit sequence of the string "OTR", encoded in tabs and
- * spaces. */
+/* The possible flags contained in a Data Message */
+#define OTRL_MSGFLAGS_IGNORE_UNREADABLE 0x01
typedef unsigned int OtrlPolicy;
@@ -121,12 +121,17 @@ OtrlMessageType otrl_proto_message_type(const char *message);
* optional chain of TLVs. A newly-allocated string will be returned in
* *encmessagep. */
gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
- const char *msg, const OtrlTLV *tlvs);
+ const char *msg, const OtrlTLV *tlvs, unsigned char flags);
+
+/* Extract the flags from an otherwise unreadable Data Message. */
+gcry_error_t otrl_proto_data_read_flags(const char *datamsg,
+ unsigned char *flagsp);
/* Accept an OTR Data Message in datamsg. Decrypt it and put the
- * plaintext into *plaintextp, and any TLVs into tlvsp. */
+ * plaintext into *plaintextp, and any TLVs into tlvsp. Put any
+ * received flags into *flagsp (if non-NULL). */
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
- ConnContext *context, const char *datamsg);
+ ConnContext *context, const char *datamsg, unsigned char *flagsp);
/* Accumulate a potential fragment into the current context. */
OtrlFragmentResult otrl_proto_fragment_accumulate(char **unfragmessagep,
diff --git a/src/tests.c b/src/tests.c
index 19e162e..b3455d0 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -204,7 +204,23 @@ void test_crash1(void)
alicecontext->sesskeys[1][0].sendenc,
alicecontext->sesskeys[1][1].sendenc);
sending(BOB, ALICE, "then."); dispatch();
+}
+
+void test_refresh(void)
+{
+ printf("\n\n*** Testing refresh ***\n\n");
+
+ otrl_context_forget_all(us);
+ ALICEPOLICY = OTRL_POLICY_DEFAULT;
+ sending(ALICE, BOB, "?OTR?"); dispatch();
+ sending(ALICE, BOB, "Hi!"); dispatch();
+ sending(BOB, ALICE, "There!"); dispatch();
+ sending(ALICE, BOB, "You!"); dispatch();
+ sending(ALICE, BOB, "Guys!"); dispatch();
+ sending(BOB, ALICE, "?OTR?"); dispatch();
+ sending(ALICE, BOB, "Refreshed!"); dispatch();
+ sending(BOB, ALICE, "Also refreshed!"); dispatch();
}
int main(int argc, char **argv)
@@ -220,7 +236,7 @@ int main(int argc, char **argv)
test(2,1);
test_unreadable();
test_crash1();
-
+ test_refresh();
otrl_userstate_free(us);
diff --git a/toolkit/otr_parse.c b/toolkit/otr_parse.c
index 9a88659..afdac72 100644
--- a/toolkit/otr_parse.c
+++ b/toolkit/otr_parse.c
@@ -120,6 +120,9 @@ static void parse(const char *msg)
break;
}
printf("Data Message:\n");
+ if (datamsg->flags >= 0) {
+ dump_int(stdout, "\tFlags", datamsg->flags);
+ }
dump_int(stdout, "\tSender keyid", datamsg->sender_keyid);
dump_int(stdout, "\tRcpt keyid", datamsg->rcpt_keyid);
dump_mpi(stdout, "\tDH y", datamsg->y);
diff --git a/toolkit/otr_remac.c b/toolkit/otr_remac.c
index e644c4d..0ffe90b 100644
--- a/toolkit/otr_remac.c
+++ b/toolkit/otr_remac.c
@@ -30,8 +30,8 @@
static void usage(const char *progname)
{
- fprintf(stderr, "Usage: %s mackey snd_keyid rcp_keyid pubkey counter "
- "encdata revealed_mackeys\n"
+ fprintf(stderr, "Usage: %s mackey flags snd_keyid rcp_keyid pubkey "
+ "counter encdata revealed_mackeys\n"
"Make a new Data message, with the given pieces (note that the\n"
"data part is already encrypted). MAC it with the given mackey.\n"
"mackey, pubkey, counter, encdata, and revealed_mackeys are given\n"
@@ -44,6 +44,7 @@ int main(int argc, char **argv)
unsigned char *mackey;
size_t mackeylen;
unsigned int snd_keyid, rcp_keyid;
+ int flags;
unsigned char *pubkey;
size_t pubkeylen;
gcry_mpi_t pubv;
@@ -55,7 +56,7 @@ int main(int argc, char **argv)
size_t mackeyslen;
char *newdatamsg;
- if (argc != 8) {
+ if (argc != 9) {
usage(argv[0]);
}
@@ -69,24 +70,29 @@ int main(int argc, char **argv)
usage(argv[0]);
}
- if (sscanf(argv[2], "%u", &snd_keyid) != 1) {
+ if (sscanf(argv[2], "%d", &flags) != 1) {
+ fprintf(stderr, "Unparseable flags given.\n");
+ usage(argv[0]);
+ }
+
+ if (sscanf(argv[3], "%u", &snd_keyid) != 1) {
fprintf(stderr, "Unparseable snd_keyid given.\n");
usage(argv[0]);
}
- if (sscanf(argv[3], "%u", &rcp_keyid) != 1) {
+ if (sscanf(argv[4], "%u", &rcp_keyid) != 1) {
fprintf(stderr, "Unparseable rcp_keyid given.\n");
usage(argv[0]);
}
- argv_to_buf(&pubkey, &pubkeylen, argv[4]);
+ argv_to_buf(&pubkey, &pubkeylen, argv[5]);
if (!pubkey) {
usage(argv[0]);
}
gcry_mpi_scan(&pubv, GCRYMPI_FMT_USG, pubkey, pubkeylen, NULL);
free(pubkey);
- argv_to_buf(&ctr, &ctrlen, argv[5]);
+ argv_to_buf(&ctr, &ctrlen, argv[6]);
if (!ctr) {
usage(argv[0]);
}
@@ -96,18 +102,18 @@ int main(int argc, char **argv)
usage(argv[0]);
}
- argv_to_buf(&encdata, &encdatalen, argv[6]);
+ argv_to_buf(&encdata, &encdatalen, argv[7]);
if (!encdata) {
usage(argv[0]);
}
- argv_to_buf(&mackeys, &mackeyslen, argv[7]);
+ argv_to_buf(&mackeys, &mackeyslen, argv[8]);
if (!mackeys) {
usage(argv[0]);
}
- newdatamsg = assemble_datamsg(mackey, snd_keyid, rcp_keyid, pubv, ctr,
- encdata, encdatalen, mackeys, mackeyslen);
+ newdatamsg = assemble_datamsg(mackey, flags, snd_keyid, rcp_keyid,
+ pubv, ctr, encdata, encdatalen, mackeys, mackeyslen);
printf("%s\n", newdatamsg);
free(newdatamsg);
diff --git a/toolkit/parse.c b/toolkit/parse.c
index 456754c..e07c86a 100644
--- a/toolkit/parse.c
+++ b/toolkit/parse.c
@@ -375,6 +375,7 @@ DataMsg parse_datamsg(const char *msg)
size_t lenp;
unsigned char *raw = decode(msg, &lenp);
unsigned char *bufp = raw;
+ unsigned char version;
if (!raw) goto inv;
datam = calloc(1, sizeof(struct s_DataMsg));
@@ -388,9 +389,18 @@ DataMsg parse_datamsg(const char *msg)
datam->macstart = bufp;
require_len(3);
- if (memcmp(bufp, "\x00\x01\x03", 3)) goto inv;
+ if (memcmp(bufp, "\x00\x01\x03", 3) && memcmp(bufp, "\x00\x02\x03", 3))
+ goto inv;
+ version = bufp[1];
bufp += 3; lenp -= 3;
+ if (version == 2) {
+ require_len(1);
+ datam->flags = bufp[0];
+ bufp += 1; lenp -= 1;
+ } else {
+ datam->flags = -1;
+ }
read_int(datam->sender_keyid);
read_int(datam->rcpt_keyid);
read_mpi(datam->y);
@@ -425,11 +435,12 @@ char *remac_datamsg(DataMsg datamsg, unsigned char mackey[20])
size_t base64len;
char *outmsg;
unsigned char *raw, *bufp;
+ unsigned char version = (datamsg->flags >= 0 ? 2 : 1);
/* Calculate the size of the message that will result */
gcry_mpi_print(GCRYMPI_FMT_USG, NULL, 0, &ylen, datamsg->y);
- rawlen = 3 + 4 + 4 + 4 + ylen + 8 + 4 + datamsg->encmsglen + 20 +
- 4 + datamsg->mackeyslen;
+ rawlen = 3 + (version == 2 ? 1 : 0) + 4 + 4 + 4 + ylen + 8 + 4 +
+ datamsg->encmsglen + 20 + 4 + datamsg->mackeyslen;
/* Construct the new raw message (note that some of the pieces may
* have been altered, so we construct it from scratch). */
@@ -446,8 +457,16 @@ char *remac_datamsg(DataMsg datamsg, unsigned char mackey[20])
datamsg->raw = raw;
datamsg->rawlen = rawlen;
- memmove(bufp, "\x00\x01\x03", 3);
+ if (version == 1) {
+ memmove(bufp, "\x00\x01\x03", 3);
+ } else {
+ memmove(bufp, "\x00\x02\x03", 3);
+ }
bufp += 3; lenp -= 3;
+ if (version == 2) {
+ bufp[0] = datamsg->flags;
+ bufp += 1; lenp -= 1;
+ }
write_int(datamsg->sender_keyid);
write_int(datamsg->rcpt_keyid);
write_mpi(datamsg->y, ylen);
@@ -481,14 +500,15 @@ char *remac_datamsg(DataMsg datamsg, unsigned char mackey[20])
/* Assemble a new Data Message from its pieces. Return a
* newly-allocated string containing the base64 representation. */
-char *assemble_datamsg(unsigned char mackey[20], unsigned int sender_keyid,
- unsigned int rcpt_keyid, gcry_mpi_t y, unsigned char ctr[8],
- unsigned char *encmsg, size_t encmsglen, unsigned char *mackeys,
- size_t mackeyslen)
+char *assemble_datamsg(unsigned char mackey[20], int flags,
+ unsigned int sender_keyid, unsigned int rcpt_keyid, gcry_mpi_t y,
+ unsigned char ctr[8], unsigned char *encmsg, size_t encmsglen,
+ unsigned char *mackeys, size_t mackeyslen)
{
DataMsg datam = calloc(1, sizeof(struct s_DataMsg));
char *newmsg = NULL;
if (!datam) goto inv;
+ datam->flags = flags;
datam->sender_keyid = sender_keyid;
datam->rcpt_keyid = rcpt_keyid;
datam->y = gcry_mpi_copy(y);
diff --git a/toolkit/parse.h b/toolkit/parse.h
index 9329289..1db65bc 100644
--- a/toolkit/parse.h
+++ b/toolkit/parse.h
@@ -36,6 +36,7 @@ typedef struct s_KeyExchMsg {
typedef struct s_DataMsg {
unsigned char *raw; /* The base64-decoded data; must be free()d */
size_t rawlen;
+ int flags;
unsigned int sender_keyid;
unsigned int rcpt_keyid;
gcry_mpi_t y;
@@ -130,10 +131,10 @@ char *remac_datamsg(DataMsg datamsg, unsigned char mackey[20]);
/* Assemble a new Data Message from its pieces. Return a
* newly-allocated string containing the base64 representation. */
-char *assemble_datamsg(unsigned char mackey[20], unsigned int sender_keyid,
- unsigned int rcpt_keyid, gcry_mpi_t y, unsigned char ctr[8],
- unsigned char *encmsg, size_t encmsglen, unsigned char *mackeys,
- size_t mackeyslen);
+char *assemble_datamsg(unsigned char mackey[20], int flags,
+ unsigned int sender_keyid, unsigned int rcpt_keyid, gcry_mpi_t y,
+ unsigned char ctr[8], unsigned char *encmsg, size_t encmsglen,
+ unsigned char *mackeys, size_t mackeyslen);
/* Deallocate a DataMsg and all of the data it points to */
void free_datamsg(DataMsg datamsg);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/libotr.git
More information about the Pkg-privacy-commits
mailing list