[Pkg-privacy-commits] [libotr] 51/225: * version.h: Change version number to 4.0.0 (but still far from release).
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:44:52 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 a2f9a4986dfa1dd082e5cf4f04f96de133e2b66b
Author: cypherpunk <cypherpunk>
Date: Wed Jul 2 15:36:56 2008 +0000
* version.h: Change version number to 4.0.0 (but still far from
release).
* tlv.h:
* proto.h:
* proto.c:
* message.h:
* message.c:
* dh.h:
* dh.c: Support for applications requesting an extra session key
that can be used for things like file transfers.
* message.h:
* message.c: Applications now use the handle_smp_event callback
to handle SMP events, rather than having to hardcode part of the
SMP state machine themselves.
---
ChangeLog | 19 ++++
src/dh.c | 7 ++
src/dh.h | 3 +
src/message.c | 324 ++++++++++++++++++++++++++++++++++++++++++++--------------
src/message.h | 25 +++++
src/proto.c | 11 +-
src/proto.h | 6 +-
src/tlv.h | 7 ++
src/version.h | 6 +-
9 files changed, 325 insertions(+), 83 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a919221..de9902d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-07-02:
+
+ * version.h: Change version number to 4.0.0 (but still far from
+ release).
+
+ * tlv.h:
+ * proto.h:
+ * proto.c:
+ * message.h:
+ * message.c:
+ * dh.h:
+ * dh.c: Support for applications requesting an extra session key
+ that can be used for things like file transfers.
+
+ * message.h:
+ * message.c: Applications now use the handle_smp_event callback
+ to handle SMP events, rather than having to hardcode part of the
+ SMP state machine themselves.
+
2008-06-15:
* README: Release version 3.2.0.
diff --git a/src/dh.c b/src/dh.c
index 610c84e..8ffe1ba 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -200,6 +200,12 @@ gcry_error_t otrl_dh_session(DH_sesskeys *sess, const DH_keypair *kp,
err = gcry_md_setkey(sess->rcvmac, sess->rcvmackey, 20);
if (err) goto err;
+ /* Calculate the extra key (used if applications wish to extract a
+ * symmetric key for transferring files, or something like that) */
+ /* XXX: Document this in the protocol spec */
+ gabdata[0] = 0xff;
+ gcry_md_hash_buffer(GCRY_MD_SHA256, sess->extrakey, gabdata, gablen+5);
+
gcry_free(gabdata);
gcry_free(hashdata);
return gcry_error(GPG_ERR_NO_ERROR);
@@ -442,6 +448,7 @@ void otrl_dh_session_blank(DH_sesskeys *sess)
memset(sess->rcvmackey, 0, 20);
sess->sendmacused = 0;
sess->rcvmacused = 0;
+ memset(sess->extrakey, 0, OTRL_EXTRAKEY_BYTES);
}
/* Increment the top half of a counter block */
diff --git a/src/dh.h b/src/dh.h
index d68328f..facf043 100644
--- a/src/dh.h
+++ b/src/dh.h
@@ -33,6 +33,8 @@ typedef enum {
OTRL_SESSIONID_SECOND_HALF_BOLD
} OtrlSessionIdHalf;
+#define OTRL_EXTRAKEY_BYTES 32
+
typedef struct {
unsigned char sendctr[16];
unsigned char rcvctr[16];
@@ -44,6 +46,7 @@ typedef struct {
gcry_md_hd_t rcvmac;
unsigned char rcvmackey[20];
int rcvmacused;
+ unsigned char extrakey[OTRL_EXTRAKEY_BYTES];
} DH_sesskeys;
/*
diff --git a/src/message.c b/src/message.c
index 704bb5c..a0a0cd0 100644
--- a/src/message.c
+++ b/src/message.c
@@ -106,6 +106,10 @@ gcry_error_t otrl_message_sending(OtrlUserState us,
return gcry_error(GPG_ERR_NO_ERROR);
}
+ /* XXX: Add flags to the policy specifying whether to treat a typed
+ * "?OTR?" as a signal to start OTR, or just an ordinary message,
+ * for (1) unencrypted conversations, (2) encrypted conversations. */
+
/* If this is an OTR Query message, don't encrypt it. */
if (otrl_proto_message_type(message) == OTRL_MSGTYPE_QUERY) {
/* Replace the "?OTR?" with a custom message */
@@ -921,6 +925,7 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
char *buf;
const char *format;
const char *displayaccountname;
+ unsigned char *extrakey;
unsigned char flags;
NextExpectedSMP nextMsg;
@@ -986,8 +991,9 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
break;
case OTRL_MSGSTATE_ENCRYPTED:
+ extrakey = gcry_malloc_secure(OTRL_EXTRAKEY_BYTES);
err = otrl_proto_accept_data(&plaintext, &tlvs, context,
- message, &flags);
+ message, &flags, extrakey);
if (err) {
int is_conflict =
(gpg_err_code(err) == GPG_ERR_CONFLICT);
@@ -1030,98 +1036,264 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
otrl_context_force_finished(context);
}
+ /* If the other side told us to use the current
+ * extra symmetric key, let the application know. */
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SYMKEY);
+ if (tlv && otrl_api_version >= 0x040000) {
+ if (ops->received_symkey) {
+ ops->received_symkey(opdata, context, tlv,
+ extrakey);
+ }
+ }
+ gcry_free(extrakey);
+ extrakey = NULL;
+
/* If TLVs contain SMP data, process it */
nextMsg = context->smstate->nextExpected;
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q);
- if (tlv && nextMsg == OTRL_SMP_EXPECT1) {
- /* We can only do the verification half now.
- * We must wait for the secret to be entered
- * to continue. */
- char *question = (char *)tlv->data;
- char *qend = memchr(question, '\0', tlv->len - 1);
- size_t qlen = qend ? (qend - question + 1) : tlv->len;
- otrl_sm_step2a(context->smstate, tlv->data + qlen,
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q);
+ if (tlv) {
+ if (nextMsg == OTRL_SMP_EXPECT1) {
+ /* We can only do the verification half now.
+ * We must wait for the secret to be entered
+ * to continue. */
+ char *question = (char *)tlv->data;
+ char *qend = memchr(question, '\0', tlv->len - 1);
+ size_t qlen = qend ? (qend - question + 1) :
+ tlv->len;
+ otrl_sm_step2a(context->smstate, tlv->data + qlen,
tlv->len - qlen, 1);
- }
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
- if (tlv && nextMsg == OTRL_SMP_EXPECT1) {
- /* We can only do the verification half now.
- * We must wait for the secret to be entered
- * to continue. */
- otrl_sm_step2a(context->smstate, tlv->data, tlv->len,
- 0);
- }
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
- if (tlv && nextMsg == OTRL_SMP_EXPECT2) {
- unsigned char* nextmsg;
- int nextmsglen;
- OtrlTLV *sendtlv;
- char *sendsmp;
- otrl_sm_step3(context->smstate, tlv->data, tlv->len,
- &nextmsg, &nextmsglen);
-
- if (context->smstate->sm_prog_state !=
- OTRL_SMP_PROG_CHEATED) {
- /* Send msg with next smp msg content */
- sendtlv = otrl_tlv_new(OTRL_TLV_SMP3, nextmsglen,
- nextmsg);
- err = otrl_proto_create_data(&sendsmp,
+
+ if (context->smstate->sm_prog_state !=
+ OTRL_SMP_PROG_CHEATED) {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ASK_FOR_ANSWER,
+ context, 25, question);
+ }
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_CHEATED, context,
+ 0, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ context->smstate->sm_prog_state =
+ OTRL_SMP_PROG_OK;
+ }
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ERROR, context,
+ 0, NULL);
+ }
+ }
+ }
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
+ if (tlv) {
+ if (nextMsg == OTRL_SMP_EXPECT1) {
+ /* We can only do the verification half now.
+ * We must wait for the secret to be entered
+ * to continue. */
+ otrl_sm_step2a(context->smstate, tlv->data,
+ tlv->len, 0);
+ if (context->smstate->sm_prog_state !=
+ OTRL_SMP_PROG_CHEATED) {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ASK_FOR_SECRET,
+ context, 25, NULL);
+ }
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_CHEATED,
+ context, 0, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ context->smstate->sm_prog_state =
+ OTRL_SMP_PROG_OK;
+ }
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ERROR, context,
+ 0, NULL);
+ }
+ }
+ }
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
+ if (tlv) {
+ if (nextMsg == OTRL_SMP_EXPECT2) {
+ unsigned char* nextmsg;
+ int nextmsglen;
+ OtrlTLV *sendtlv;
+ char *sendsmp;
+ otrl_sm_step3(context->smstate, tlv->data,
+ tlv->len, &nextmsg, &nextmsglen);
+
+ if (context->smstate->sm_prog_state !=
+ OTRL_SMP_PROG_CHEATED) {
+ /* Send msg with next smp msg content */
+ sendtlv = otrl_tlv_new(OTRL_TLV_SMP3,
+ nextmsglen, nextmsg);
+ err = otrl_proto_create_data(&sendsmp,
context, "", sendtlv,
OTRL_MSGFLAGS_IGNORE_UNREADABLE);
- if (!err) {
+ if (!err) {
err = otrl_message_fragment_and_send(ops,
- opdata, context, sendsmp,
- OTRL_FRAGMENT_SEND_ALL, NULL);
+ opdata, context, sendsmp,
+ OTRL_FRAGMENT_SEND_ALL, NULL);
+ }
+ free(sendsmp);
+ otrl_tlv_free(sendtlv);
+
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_IN_PROGRESS,
+ context, 60, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT4;
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_CHEATED,
+ context, 0, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ context->smstate->sm_prog_state =
+ OTRL_SMP_PROG_OK;
}
- free(sendsmp);
- otrl_tlv_free(sendtlv);
- }
- free(nextmsg);
- }
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
- if (tlv && nextMsg == OTRL_SMP_EXPECT3) {
- unsigned char* nextmsg;
- int nextmsglen;
- OtrlTLV *sendtlv;
- char *sendsmp;
- err = otrl_sm_step4(context->smstate, tlv->data,
- tlv->len, &nextmsg, &nextmsglen);
- /* Set trust level based on result */
- if (context->smstate->received_question == 0) {
- set_smp_trust(ops, opdata, context,
+ free(nextmsg);
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ERROR, context,
+ 0, NULL);
+ }
+ }
+ }
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
+ if (tlv) {
+ if (nextMsg == OTRL_SMP_EXPECT3) {
+ unsigned char* nextmsg;
+ int nextmsglen;
+ OtrlTLV *sendtlv;
+ char *sendsmp;
+ err = otrl_sm_step4(context->smstate, tlv->data,
+ tlv->len, &nextmsg, &nextmsglen);
+ /* Set trust level based on result */
+ if (context->smstate->received_question == 0) {
+ set_smp_trust(ops, opdata, context,
(err == gcry_error(GPG_ERR_NO_ERROR)));
- }
-
- if (context->smstate->sm_prog_state !=
- OTRL_SMP_PROG_CHEATED) {
- /* Send msg with next smp msg content */
- sendtlv = otrl_tlv_new(OTRL_TLV_SMP4, nextmsglen,
- nextmsg);
- err = otrl_proto_create_data(&sendsmp,
+ }
+
+ if (context->smstate->sm_prog_state !=
+ OTRL_SMP_PROG_CHEATED) {
+ /* Send msg with next smp msg content */
+ sendtlv = otrl_tlv_new(OTRL_TLV_SMP4,
+ nextmsglen, nextmsg);
+ err = otrl_proto_create_data(&sendsmp,
context, "", sendtlv,
OTRL_MSGFLAGS_IGNORE_UNREADABLE);
- if (!err) {
+ if (!err) {
err = otrl_message_fragment_and_send(ops,
- opdata, context, sendsmp,
- OTRL_FRAGMENT_SEND_ALL, NULL);
+ opdata, context, sendsmp,
+ OTRL_FRAGMENT_SEND_ALL, NULL);
+ }
+ free(sendsmp);
+ otrl_tlv_free(sendtlv);
+
+ if (ops->handle_smp_event) {
+ OtrlSMPEvent succorfail =
+ context->smstate->sm_prog_state ==
+ OTRL_SMP_PROG_SUCCEEDED ?
+ OTRL_SMPEVENT_SUCCESS :
+ OTRL_SMPEVENT_FAILURE;
+ ops->handle_smp_event(opdata, succorfail,
+ context, 100, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_CHEATED,
+ context, 0, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ context->smstate->sm_prog_state =
+ OTRL_SMP_PROG_OK;
}
- free(sendsmp);
- otrl_tlv_free(sendtlv);
- }
- free(nextmsg);
- }
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4);
- if (tlv && nextMsg == OTRL_SMP_EXPECT4) {
- err = otrl_sm_step5(context->smstate, tlv->data,
+ free(nextmsg);
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ERROR, context,
+ 0, NULL);
+ }
+ }
+ }
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4);
+ if (tlv) {
+ if (nextMsg == OTRL_SMP_EXPECT4) {
+ err = otrl_sm_step5(context->smstate, tlv->data,
tlv->len);
- /* Set trust level based on result */
- set_smp_trust(ops, opdata, context,
+ /* Set trust level based on result */
+ set_smp_trust(ops, opdata, context,
(err == gcry_error(GPG_ERR_NO_ERROR)));
- }
- tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
+
+ if (context->smstate->sm_prog_state !=
+ OTRL_SMP_PROG_CHEATED) {
+ if (ops->handle_smp_event) {
+ OtrlSMPEvent succorfail =
+ context->smstate->sm_prog_state ==
+ OTRL_SMP_PROG_SUCCEEDED ?
+ OTRL_SMPEVENT_SUCCESS :
+ OTRL_SMPEVENT_FAILURE;
+ ops->handle_smp_event(opdata, succorfail,
+ context, 100, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_CHEATED,
+ context, 0, NULL);
+ }
+ context->smstate->nextExpected =
+ OTRL_SMP_EXPECT1;
+ context->smstate->sm_prog_state =
+ OTRL_SMP_PROG_OK;
+ }
+ } else {
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata,
+ OTRL_SMPEVENT_ERROR, context,
+ 0, NULL);
+ }
+ }
+ }
+
+ tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
if (tlv) {
context->smstate->nextExpected = OTRL_SMP_EXPECT1;
+ if (ops->handle_smp_event) {
+ ops->handle_smp_event(opdata, OTRL_SMPEVENT_ABORT,
+ context, 0, NULL);
+ }
}
+
if (plaintext[0] == '\0') {
/* If it's a heartbeat (an empty message), don't
* display it to the user, but log a debug message. */
diff --git a/src/message.h b/src/message.h
index e658e9d..1c3286f 100644
--- a/src/message.h
+++ b/src/message.h
@@ -20,6 +20,18 @@
#ifndef __MESSAGE_H__
#define __MESSAGE_H__
+/* These define the events used to indicate status of SMP to the UI */
+typedef enum {
+ OTRL_SMPEVENT_ERROR,
+ OTRL_SMPEVENT_ABORT,
+ OTRL_SMPEVENT_CHEATED,
+ OTRL_SMPEVENT_ASK_FOR_ANSWER,
+ OTRL_SMPEVENT_ASK_FOR_SECRET,
+ OTRL_SMPEVENT_IN_PROGRESS,
+ OTRL_SMPEVENT_SUCCESS,
+ OTRL_SMPEVENT_FAILURE
+} OtrlSMPEvent;
+
typedef enum {
OTRL_NOTIFY_ERROR,
OTRL_NOTIFY_WARNING,
@@ -108,6 +120,19 @@ typedef struct s_OtrlMessageAppOps {
/* Deallocate a string returned by account_name */
void (*account_name_free)(void *opdata, const char *account_name);
+ /* We received a request from the buddy to use the current "extra"
+ * symmetric key. The key will be passed in symkey, of length
+ * OTRL_EXTRAKEY_BYTES. The TLV which carried the request will be
+ * passed in tlv, so that the applications can communicate other
+ * identifiers (some id for the data transfer, for example). */
+ void (*received_symkey)(void *opdata, ConnContext *context,
+ OtrlTLV *tlv, const unsigned char *symkey);
+
+ /* Update the auth UI with respect to SMP events */
+ void (*handle_smp_event)(void *opdata, OtrlSMPEvent smp_event,
+ ConnContext *context, unsigned short progress_percent,
+ char *question);
+
} OtrlMessageAppOps;
/* Deallocate a message allocated by other otrl_message_* routines. */
diff --git a/src/proto.c b/src/proto.c
index 3f8c987..992dda3 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -572,9 +572,11 @@ invval:
/* Accept an OTR Data Message in datamsg. Decrypt it and put the
* plaintext into *plaintextp, and any TLVs into tlvsp. Put any
- * received flags into *flagsp (if non-NULL). */
+ * received flags into *flagsp (if non-NULL). Put the current extra
+ * symmetric key into extrakey (if non-NULL). */
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
- ConnContext *context, const char *datamsg, unsigned char *flagsp)
+ ConnContext *context, const char *datamsg, unsigned char *flagsp,
+ unsigned char *extrakey)
{
char *otrtag, *endtag;
gcry_error_t err;
@@ -706,6 +708,11 @@ gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
err = gcry_cipher_decrypt(sess->rcvenc, data, datalen, NULL, 0);
if (err) goto err;
+ /* Save a copy of the current extra key */
+ if (extrakey) {
+ memmove(extrakey, sess->extrakey, OTRL_EXTRAKEY_BYTES);
+ }
+
/* See if either set of keys needs rotating */
if (recipient_keyid == context->our_keyid) {
diff --git a/src/proto.h b/src/proto.h
index d7b0ae6..035b4d1 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -135,9 +135,11 @@ gcry_error_t otrl_proto_data_read_flags(const char *datamsg,
/* Accept an OTR Data Message in datamsg. Decrypt it and put the
* plaintext into *plaintextp, and any TLVs into tlvsp. Put any
- * received flags into *flagsp (if non-NULL). */
+ * received flags into *flagsp (if non-NULL). Put the current extra
+ * symmetric key into extrakey (if non-NULL). */
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
- ConnContext *context, const char *datamsg, unsigned char *flagsp);
+ ConnContext *context, const char *datamsg, unsigned char *flagsp,
+ unsigned char *extrakey);
/* Accumulate a potential fragment into the current context. */
OtrlFragmentResult otrl_proto_fragment_accumulate(char **unfragmessagep,
diff --git a/src/tlv.h b/src/tlv.h
index affe0d5..b5822b5 100644
--- a/src/tlv.h
+++ b/src/tlv.h
@@ -44,6 +44,13 @@ typedef struct s_OtrlTLV {
/* Like OTRL_TLV_SMP1, but there's a question for the buddy at the
* beginning */
#define OTRL_TLV_SMP1Q 0x0007
+/* Tell the application the current "extra" symmetric key */
+/* XXX: Document this in the protocol spec:
+ * The body of the TLV will begin with a 4-byte indication of what this
+ * symmetric key will be used for (file transfer, voice encryption,
+ * etc.). After that, the contents are use-specific (which file, etc.).
+ * There are no currently defined uses. */
+#define OTRL_TLV_SYMKEY 0x0008
/* Make a single TLV, copying the supplied data */
OtrlTLV *otrl_tlv_new(unsigned short type, unsigned short len,
diff --git a/src/version.h b/src/version.h
index 11cb586..78acf17 100644
--- a/src/version.h
+++ b/src/version.h
@@ -20,10 +20,10 @@
#ifndef __VERSION_H__
#define __VERSION_H__
-#define OTRL_VERSION "3.2.0"
+#define OTRL_VERSION "4.0.0"
-#define OTRL_VERSION_MAJOR 3
-#define OTRL_VERSION_MINOR 2
+#define OTRL_VERSION_MAJOR 4
+#define OTRL_VERSION_MINOR 0
#define OTRL_VERSION_SUB 0
#endif
--
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