]> the.earth.li Git - onak.git/blob - sigcheck.c
Fix memory leak in makewordlistfromkey()
[onak.git] / sigcheck.c
1 /*
2  * sigcheck.c - routines to check OpenPGP signatures
3  *
4  * Copyright 2012 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <stdint.h>
20
21 #include "build-config.h"
22 #include "decodekey.h"
23 #include "keyid.h"
24 #include "keystructs.h"
25 #include "log.h"
26 #include "openpgp.h"
27 #include "sigcheck.h"
28
29 #ifdef HAVE_NETTLE
30 #include <nettle/md5.h>
31 #include <nettle/ripemd160.h>
32 #include <nettle/sha.h>
33 #else
34 #include "md5.h"
35 #include "sha1.h"
36 #endif
37 #include "sha1x.h"
38
39 onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
40                         struct openpgp_packet *packet,
41                         struct openpgp_packet *sig,
42                         uint8_t *hashtype,
43                         uint8_t *hash,
44                         uint8_t **sighash)
45 {
46         size_t siglen, unhashedlen;
47         struct sha1_ctx sha1_context;
48         struct sha1x_ctx sha1x_context;
49         struct md5_ctx md5_context;
50 #ifdef HAVE_NETTLE
51         struct ripemd160_ctx ripemd160_context;
52         struct sha224_ctx sha224_context;
53         struct sha256_ctx sha256_context;
54         struct sha384_ctx sha384_context;
55         struct sha512_ctx sha512_context;
56 #endif
57         uint8_t keyheader[5];
58         uint8_t packetheader[5];
59         uint8_t trailer[10];
60         uint8_t *hashdata[8];
61         size_t hashlen[8];
62         int chunks, i;
63         uint64_t keyid;
64         onak_status_t res;
65
66         switch (sig->data[0]) {
67         case 2:
68         case 3:
69                 keyheader[0] = 0x99;
70                 keyheader[1] = key->publickey->length >> 8;
71                 keyheader[2] = key->publickey->length & 0xFF;
72                 hashdata[0] = keyheader;
73                 hashlen[0] = 3;
74                 hashdata[1] = key->publickey->data;
75                 hashlen[1] = key->publickey->length;
76                 chunks = 2;
77
78                 *hashtype = sig->data[16];
79
80                 if (packet != NULL) {
81                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
82                                 packetheader[0] = 0x99;
83                                 packetheader[1] = packet->length >> 8;
84                                 packetheader[2] = packet->length & 0xFF;
85                                 hashdata[chunks] = packetheader;
86                                 hashlen[chunks] = 3;
87                                 chunks++;
88                         }
89
90                         // TODO: Things other than UIDS/subkeys?
91                         hashdata[chunks] = packet->data;
92                         hashlen[chunks] = packet->length;
93                         chunks++;
94                 }
95
96                 hashdata[chunks] = &sig->data[2];
97                 hashlen[chunks] = 5;
98                 chunks++;
99                 *sighash = &sig->data[17];
100                 break;
101         case 4:
102                 keyheader[0] = 0x99;
103                 keyheader[1] = key->publickey->length >> 8;
104                 keyheader[2] = key->publickey->length & 0xFF;
105                 hashdata[0] = keyheader;
106                 hashlen[0] = 3;
107                 hashdata[1] = key->publickey->data;
108                 hashlen[1] = key->publickey->length;
109                 chunks = 2;
110
111                 *hashtype = sig->data[3];
112
113                 /* Check to see if this is an X509 based signature */
114                 if (sig->data[2] == 0 || sig->data[2] == 100) {
115                         size_t len;
116
117                         keyid = 0;
118                         res = parse_subpackets(&sig->data[4],
119                                                 sig->length - 4, &len,
120                                                 &keyid, NULL);
121                         if (res != ONAK_E_OK) {
122                                 return res;
123                         }
124                         if (keyid == 0 &&
125                                         /* No unhashed data */
126                                         sig->data[4 + len] == 0 &&
127                                         sig->data[5 + len] == 0 &&
128                                         /* Dummy 0 checksum */
129                                         sig->data[6 + len] == 0 &&
130                                         sig->data[7 + len] == 0 &&
131                                         /* Dummy MPI of 1 */
132                                         sig->data[8 + len] == 0 &&
133                                         sig->data[9 + len] == 1 &&
134                                         sig->data[10 + len] == 1) {
135                                 return ONAK_E_UNSUPPORTED_FEATURE;
136                         }
137                 }
138
139                 if (packet != NULL) {
140                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
141                                 packetheader[0] = 0x99;
142                                 packetheader[1] = packet->length >> 8;
143                                 packetheader[2] = packet->length & 0xFF;
144                                 hashdata[chunks] = packetheader;
145                                 hashlen[chunks] = 3;
146                                 chunks++;
147                         } else if (packet->tag == OPENPGP_PACKET_UID ||
148                                         packet->tag == OPENPGP_PACKET_UAT) {
149                                 packetheader[0] = (packet->tag ==
150                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
151                                 packetheader[1] = packet->length >> 24;
152                                 packetheader[2] = (packet->length >> 16) & 0xFF;
153                                 packetheader[3] = (packet->length >> 8) & 0xFF;
154                                 packetheader[4] = packet->length & 0xFF;
155                                 hashdata[chunks] = packetheader;
156                                 hashlen[chunks] = 5;
157                                 chunks++;
158                         }
159                         hashdata[chunks] = packet->data;
160                         hashlen[chunks] = packet->length;
161                         chunks++;
162                 }
163
164                 hashdata[chunks] = sig->data;
165                 hashlen[chunks] = siglen = (sig->data[4] << 8) +
166                         sig->data[5] + 6;;
167                 if (siglen > sig->length) {
168                         /* Signature data exceed packet length, bogus */
169                         return ONAK_E_INVALID_PKT;
170                 }
171                 chunks++;
172
173                 trailer[0] = 4;
174                 trailer[1] = 0xFF;
175                 trailer[2] = siglen >> 24;
176                 trailer[3] = (siglen >> 16) & 0xFF;
177                 trailer[4] = (siglen >> 8) & 0xFF;
178                 trailer[5] = siglen & 0xFF;
179                 hashdata[chunks] = trailer;
180                 hashlen[chunks] = 6;
181                 chunks++;
182
183                 unhashedlen = (sig->data[siglen] << 8) +
184                         sig->data[siglen + 1];
185                 *sighash = &sig->data[siglen + unhashedlen + 2];
186                 break;
187         case 5:
188                 keyheader[0] = 0x9A;
189                 keyheader[1] = 0;
190                 keyheader[2] = 0;
191                 keyheader[3] = key->publickey->length >> 8;
192                 keyheader[4] = key->publickey->length & 0xFF;
193                 hashdata[0] = keyheader;
194                 hashlen[0] = 5;
195                 hashdata[1] = key->publickey->data;
196                 hashlen[1] = key->publickey->length;
197                 chunks = 2;
198
199                 *hashtype = sig->data[3];
200
201                 if (packet != NULL) {
202                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
203                                 packetheader[0] = 0x9A;
204                                 packetheader[1] = 0;
205                                 packetheader[2] = 0;
206                                 packetheader[3] = packet->length >> 8;
207                                 packetheader[4] = packet->length & 0xFF;
208                                 hashdata[chunks] = packetheader;
209                                 hashlen[chunks] = 5;
210                                 chunks++;
211                         } else if (packet->tag == OPENPGP_PACKET_UID ||
212                                         packet->tag == OPENPGP_PACKET_UAT) {
213                                 packetheader[0] = (packet->tag ==
214                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
215                                 packetheader[1] = packet->length >> 24;
216                                 packetheader[2] = (packet->length >> 16) & 0xFF;
217                                 packetheader[3] = (packet->length >> 8) & 0xFF;
218                                 packetheader[4] = packet->length & 0xFF;
219                                 hashdata[chunks] = packetheader;
220                                 hashlen[chunks] = 5;
221                                 chunks++;
222                         }
223                         hashdata[chunks] = packet->data;
224                         hashlen[chunks] = packet->length;
225                         chunks++;
226                 }
227
228                 hashdata[chunks] = sig->data;
229                 hashlen[chunks] = siglen = (sig->data[4] << 8) +
230                         sig->data[5] + 6;;
231                 if (siglen > sig->length) {
232                         /* Signature data exceed packet length, bogus */
233                         return ONAK_E_INVALID_PKT;
234                 }
235                 chunks++;
236
237                 trailer[0] = 5;
238                 trailer[1] = 0xFF;
239                 trailer[2] = 0;
240                 trailer[3] = 0;
241                 trailer[4] = 0;
242                 trailer[5] = 0;
243                 trailer[6] = siglen >> 24;
244                 trailer[7] = (siglen >> 16) & 0xFF;
245                 trailer[8] = (siglen >> 8) & 0xFF;
246                 trailer[9] = siglen & 0xFF;
247                 hashdata[chunks] = trailer;
248                 hashlen[chunks] = 10;
249                 chunks++;
250
251                 unhashedlen = (sig->data[siglen] << 8) +
252                         sig->data[siglen + 1];
253                 *sighash = &sig->data[siglen + unhashedlen + 2];
254                 break;
255         default:
256                 return ONAK_E_UNSUPPORTED_FEATURE;
257         }
258
259         switch (*hashtype) {
260         case OPENPGP_HASH_MD5:
261                 md5_init(&md5_context);
262                 for (i = 0; i < chunks; i++) {
263                         md5_update(&md5_context, hashlen[i], hashdata[i]);
264                 }
265                 md5_digest(&md5_context, 16, hash);
266                 break;
267         case OPENPGP_HASH_SHA1:
268                 sha1_init(&sha1_context);
269                 for (i = 0; i < chunks; i++) {
270                         sha1_update(&sha1_context, hashlen[i], hashdata[i]);
271                 }
272                 sha1_digest(&sha1_context, 20, hash);
273                 break;
274         case OPENPGP_HASH_SHA1X:
275                 sha1x_init(&sha1x_context);
276                 for (i = 0; i < chunks; i++) {
277                         sha1x_update(&sha1x_context, hashlen[i], hashdata[i]);
278                 }
279                 sha1x_digest(&sha1x_context, 20, hash);
280                 break;
281 #ifdef HAVE_NETTLE
282         case OPENPGP_HASH_RIPEMD160:
283                 ripemd160_init(&ripemd160_context);
284                 for (i = 0; i < chunks; i++) {
285                         ripemd160_update(&ripemd160_context, hashlen[i],
286                                 hashdata[i]);
287                 }
288                 ripemd160_digest(&ripemd160_context, RIPEMD160_DIGEST_SIZE,
289                         hash);
290                 break;
291         case OPENPGP_HASH_SHA224:
292                 sha224_init(&sha224_context);
293                 for (i = 0; i < chunks; i++) {
294                         sha224_update(&sha224_context, hashlen[i],
295                                 hashdata[i]);
296                 }
297                 sha224_digest(&sha224_context, SHA224_DIGEST_SIZE, hash);
298                 break;
299         case OPENPGP_HASH_SHA256:
300                 sha256_init(&sha256_context);
301                 for (i = 0; i < chunks; i++) {
302                         sha256_update(&sha256_context, hashlen[i],
303                                 hashdata[i]);
304                 }
305                 sha256_digest(&sha256_context, SHA256_DIGEST_SIZE, hash);
306                 break;
307         case OPENPGP_HASH_SHA384:
308                 sha384_init(&sha384_context);
309                 for (i = 0; i < chunks; i++) {
310                         sha384_update(&sha384_context, hashlen[i],
311                                 hashdata[i]);
312                 }
313                 sha384_digest(&sha384_context, SHA384_DIGEST_SIZE, hash);
314                 break;
315         case OPENPGP_HASH_SHA512:
316                 sha512_init(&sha512_context);
317                 for (i = 0; i < chunks; i++) {
318                         sha512_update(&sha512_context, hashlen[i],
319                                 hashdata[i]);
320                 }
321                 sha512_digest(&sha512_context, SHA512_DIGEST_SIZE, hash);
322                 break;
323 #endif
324         default:
325                 return ONAK_E_UNSUPPORTED_FEATURE;
326         }
327
328         return ONAK_E_OK;
329 }