summaryrefslogtreecommitdiffstats
path: root/comm/third_party/libotr/toolkit/otr_remac.c
blob: 1567eeb929e8127b3f3d038f73aa851c50aeb507 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 *  Off-the-Record Messaging Toolkit
 *  Copyright (C) 2004-2012  Ian Goldberg, Rob Smits, Chris Alexander,
 *                           Nikita Borisov
 *                           <otr@cypherpunks.ca>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of version 2 of the GNU General Public License as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/* system headers */
#include <stdio.h>
#include <stdlib.h>

/* libgcrypt headers */
#include <gcrypt.h>

/* toolkit headers */
#include "parse.h"
#include "sha1hmac.h"

static void usage(const char *progname)
{
    fprintf(stderr, "Usage: %s mackey sender_instance receiver_instance "
	"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"
"as strings of hex chars.  snd_keyid and rcp_keyid are decimal integers.\n",
	progname);
    exit(1);
}

int main(int argc, char **argv)
{
    unsigned char *mackey;
    size_t mackeylen;
    unsigned int snd_keyid, rcp_keyid;
    int flags;
    unsigned char version = 3;
    unsigned int sender_instance;
    unsigned int receiver_instance;
    unsigned char *pubkey;
    size_t pubkeylen;
    gcry_mpi_t pubv;
    unsigned char *ctr;
    size_t ctrlen;
    unsigned char *encdata;
    size_t encdatalen;
    unsigned char *mackeys;
    size_t mackeyslen;
    char *newdatamsg;

    if (argc != 11) {
	usage(argv[0]);
    }

    argv_to_buf(&mackey, &mackeylen, argv[1]);
    if (!mackey) {
	usage(argv[0]);
    }

    if (mackeylen != 20) {
	fprintf(stderr, "The MAC key must be 40 hex chars long.\n");
	usage(argv[0]);
    }

    if (sscanf(argv[2], "%u", &sender_instance) != 1) {
	fprintf(stderr, "Unparseable sender_instance given.\n");
	usage(argv[0]);
    }

    if (sscanf(argv[3], "%u", &receiver_instance) != 1) {
	fprintf(stderr, "Unparseable receiver_instance given.\n");
	usage(argv[0]);
    }

    if (sscanf(argv[4], "%d", &flags) != 1) {
	fprintf(stderr, "Unparseable flags given.\n");
	usage(argv[0]);
    }

    if (sscanf(argv[5], "%u", &snd_keyid) != 1) {
	fprintf(stderr, "Unparseable snd_keyid given.\n");
	usage(argv[0]);
    }

    if (sscanf(argv[6], "%u", &rcp_keyid) != 1) {
	fprintf(stderr, "Unparseable rcp_keyid given.\n");
	usage(argv[0]);
    }

    argv_to_buf(&pubkey, &pubkeylen, argv[7]);
    if (!pubkey) {
	usage(argv[0]);
    }
    gcry_mpi_scan(&pubv, GCRYMPI_FMT_USG, pubkey, pubkeylen, NULL);
    free(pubkey);

    argv_to_buf(&ctr, &ctrlen, argv[8]);
    if (!ctr) {
	usage(argv[0]);
    }

    if (ctrlen != 8) {
	fprintf(stderr, "The counter must be 16 hex chars long.\n");
	usage(argv[0]);
    }

    argv_to_buf(&encdata, &encdatalen, argv[9]);
    if (!encdata) {
	usage(argv[0]);
    }

    argv_to_buf(&mackeys, &mackeyslen, argv[10]);
    if (!mackeys) {
	usage(argv[0]);
    }

    newdatamsg = assemble_datamsg(mackey, version, sender_instance,
	    receiver_instance, flags, snd_keyid, rcp_keyid, pubv, ctr, encdata,
	    encdatalen, mackeys, mackeyslen);
    printf("%s\n", newdatamsg);
    free(newdatamsg);

    free(mackey);
    gcry_mpi_release(pubv);
    free(ctr);
    free(encdata);
    free(mackeys);
    fflush(stdout);
    return 0;
}