27
27
/* If we ever see this sequence in a plaintext message, we'll assume the
28
28
* other side speaks OTR, and try to establish a connection. */
29
#define OTR_MESSAGE_TAG " \t \t\t\t\t \t \t \t \t \t \t "
30
/* This is the bit sequence of the string "OTR", encoded in tabs and
43
typedef struct s_OTRKeyExchangeMsg {
44
gcry_sexp_t digest_sexp; /* SHA-1 hash of the raw message,
45
except for the DSA sig; used
46
for checking the sig */
47
unsigned char is_reply; /* Was this a reply to a Key
48
Exchange Message we sent
50
unsigned char key_fingerprint[20]; /* The key fingerprint */
51
gcry_sexp_t dsa_pubkey; /* DSA public key */
52
unsigned int keyid; /* DH key id */
53
gcry_mpi_t dh_pubkey; /* DH public key */
54
gcry_sexp_t dsa_sig; /* Signature on packet */
55
} * OTRKeyExchangeMsg;
29
#define OTRL_MESSAGE_TAG_BASE " \t \t\t\t\t \t \t \t "
30
/* The following must each be of length 8 */
31
#define OTRL_MESSAGE_TAG_V1 " \t \t \t "
32
#define OTRL_MESSAGE_TAG_V2 " \t\t \t "
34
/* The possible flags contained in a Data Message */
35
#define OTRL_MSGFLAGS_IGNORE_UNREADABLE 0x01
37
typedef unsigned int OtrlPolicy;
39
#define OTRL_POLICY_ALLOW_V1 0x01
40
#define OTRL_POLICY_ALLOW_V2 0x02
41
#define OTRL_POLICY_REQUIRE_ENCRYPTION 0x04
42
#define OTRL_POLICY_SEND_WHITESPACE_TAG 0x08
43
#define OTRL_POLICY_WHITESPACE_START_AKE 0x08
44
#define OTRL_POLICY_ERROR_START_AKE 0x10
46
#define OTRL_POLICY_VERSION_MASK (OTRL_POLICY_ALLOW_V1 | OTRL_POLICY_ALLOW_V2)
48
/* For v1 compatibility */
49
#define OTRL_POLICY_NEVER 0x00
50
#define OTRL_POLICY_OPPORTUNISTIC \
51
( OTRL_POLICY_ALLOW_V1 | \
52
OTRL_POLICY_ALLOW_V2 | \
53
OTRL_POLICY_SEND_WHITESPACE_TAG | \
54
OTRL_POLICY_WHITESPACE_START_AKE | \
55
OTRL_POLICY_ERROR_START_AKE )
56
#define OTRL_POLICY_MANUAL \
57
( OTRL_POLICY_ALLOW_V1 | \
58
OTRL_POLICY_ALLOW_V2 )
59
#define OTRL_POLICY_ALWAYS \
60
( OTRL_POLICY_ALLOW_V1 | \
61
OTRL_POLICY_ALLOW_V2 | \
62
OTRL_POLICY_REQUIRE_ENCRYPTION | \
63
OTRL_POLICY_WHITESPACE_START_AKE | \
64
OTRL_POLICY_ERROR_START_AKE )
65
#define OTRL_POLICY_DEFAULT OTRL_POLICY_OPPORTUNISTIC
69
OTRL_MSGTYPE_TAGGEDPLAINTEXT,
71
OTRL_MSGTYPE_DH_COMMIT,
73
OTRL_MSGTYPE_REVEALSIG,
74
OTRL_MSGTYPE_SIGNATURE,
75
OTRL_MSGTYPE_V1_KEYEXCH,
82
OTRL_FRAGMENT_UNFRAGMENTED,
83
OTRL_FRAGMENT_INCOMPLETE,
84
OTRL_FRAGMENT_COMPLETE
57
87
/* Initialize the OTR library. Pass the version of the API you are
68
98
* the OTR library. */
69
99
const char *otrl_version(void);
71
/* Create a public key block from a private key */
72
gcry_error_t otrl_proto_make_pubkey(unsigned char **pubbufp, size_t *publenp,
75
101
/* Return a pointer to a newly-allocated OTR query message, customized
76
102
* with our name. The caller should free() the result when he's done
78
char *otrl_proto_default_query_msg(const char *ourname);
104
char *otrl_proto_default_query_msg(const char *ourname, OtrlPolicy policy);
106
/* Return the best version of OTR support by both sides, given an OTR
107
* Query Message and the local policy. */
108
unsigned int otrl_proto_query_bestversion(const char *querymsg,
111
/* Locate any whitespace tag in this message, and return the best
112
* version of OTR support on both sides. Set *starttagp and *endtagp to
113
* the start and end of the located tag, so that it can be snipped out. */
114
unsigned int otrl_proto_whitespace_bestversion(const char *msg,
115
const char **starttagp, const char **endtagp, OtrlPolicy policy);
80
117
/* Return the Message type of the given message. */
81
OTRMessageType otrl_proto_message_type(const char *message);
83
/* Create a Key Exchange message for our correspondent. If we need a
84
* private key and don't have one, create_privkey will be called. Use
85
* the privkeys from the given OtrlUserState. */
86
gcry_error_t otrl_proto_create_key_exchange(OtrlUserState us,
87
char **messagep, ConnContext *context, unsigned char is_reply,
88
void (*create_privkey)(void *create_privkey_data,
89
const char *accountname, const char *protocol),
90
void *create_privkey_data);
92
/* Deallocate an OTRKeyExchangeMsg returned from proto_parse_key_exchange */
93
void otrl_proto_free_key_exchange(OTRKeyExchangeMsg kem);
95
/* Parse a purported Key Exchange message. Possible error code portions
96
* of the return value:
97
* GPG_ERR_NO_ERROR: Success
98
* GPG_ERR_ENOMEM: Out of memory condition
99
* GPG_ERR_INV_VALUE: The message was not a well-formed Key Exchange
101
* GPG_ERR_BAD_SIGNATURE: The signature on the message didn't verify
103
gcry_error_t otrl_proto_parse_key_exchange(OTRKeyExchangeMsg *kemp,
106
/* Deal with a Key Exchange Message once it's been received and passed
107
* all the validity and UI ("accept this fingerprint?") tests.
108
* context/fprint is the ConnContext and Fingerprint to which it
109
* belongs. Use the given OtrlUserState to look up any necessary
110
* private keys. It is the caller's responsibility to
111
* otrl_proto_free_key_exchange(kem) when we're done. If *messagep gets
112
* set to non-NULL by this function, then it's a message that needs to
113
* get sent to the correspondent. If we need a private key and don't
114
* have one, create_privkey will be called. */
115
gcry_error_t otrl_proto_accept_key_exchange(OtrlUserState us,
116
ConnContext *context, Fingerprint *fprint, OTRKeyExchangeMsg kem,
118
void (*create_privkey)(void *create_privkey_data,
119
const char *accountname, const char *protocol),
120
void *create_privkey_data);
118
OtrlMessageType otrl_proto_message_type(const char *message);
122
120
/* Create an OTR Data message. Pass the plaintext as msg, and an
123
121
* optional chain of TLVs. A newly-allocated string will be returned in
124
122
* *encmessagep. */
125
123
gcry_error_t otrl_proto_create_data(char **encmessagep, ConnContext *context,
126
const char *msg, OtrlTLV *tlvs);
124
const char *msg, const OtrlTLV *tlvs, unsigned char flags);
126
/* Extract the flags from an otherwise unreadable Data Message. */
127
gcry_error_t otrl_proto_data_read_flags(const char *datamsg,
128
unsigned char *flagsp);
128
130
/* Accept an OTR Data Message in datamsg. Decrypt it and put the
129
* plaintext into *plaintextp, and any TLVs into tlvsp. */
131
* plaintext into *plaintextp, and any TLVs into tlvsp. Put any
132
* received flags into *flagsp (if non-NULL). */
130
133
gcry_error_t otrl_proto_accept_data(char **plaintextp, OtrlTLV **tlvsp,
131
ConnContext *context, const char *datamsg);
134
ConnContext *context, const char *datamsg, unsigned char *flagsp);
136
/* Accumulate a potential fragment into the current context. */
137
OtrlFragmentResult otrl_proto_fragment_accumulate(char **unfragmessagep,
138
ConnContext *context, const char *msg);