]> the.earth.li Git - onak.git/blob - keyid.c
Bump debhelper compat level to 13
[onak.git] / keyid.c
1 /*
2  * keyid.c - Routines to calculate key IDs.
3  *
4  * Copyright 2002,2011 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 <string.h>
20 #include <sys/types.h>
21 #include <arpa/inet.h>
22
23 #include "build-config.h"
24 #include "keyid.h"
25 #include "keystructs.h"
26 #include "onak.h"
27 #include "parsekey.h"
28 #include "mem.h"
29 #include "merge.h"
30
31 #ifdef HAVE_NETTLE
32 #include <nettle/md5.h>
33 #include <nettle/ripemd160.h>
34 #include <nettle/sha.h>
35 #else
36 #include "md5.h"
37 #include "sha1.h"
38 #endif
39
40 uint64_t fingerprint2keyid(struct openpgp_fingerprint *fingerprint)
41 {
42         uint64_t keyid;
43         int i;
44
45         switch (fingerprint->length) {
46         case 20:
47                 /* v4, keyid is last 64 bits */
48                 for (keyid = 0, i = 12; i < 20; i++) {
49                         keyid <<= 8;
50                         keyid += fingerprint->fp[i];
51                 }
52                 break;
53         case 32:
54                 /* v5, keyid is first 64 bits */
55                 for (keyid = 0, i = 0; i < 8; i++) {
56                         keyid <<= 8;
57                         keyid += fingerprint->fp[i];
58                 }
59                 break;
60         default:
61                 keyid = (uint64_t) -1;
62         }
63
64         return keyid;
65 }
66
67
68 /**
69  *      get_keyid - Given a public key returns the keyid.
70  *      @publickey: The key to calculate the id for.
71  */
72 onak_status_t get_keyid(struct openpgp_publickey *publickey, uint64_t *keyid)
73 {
74         return (get_packetid(publickey->publickey, keyid));
75 }
76
77 /**
78  *      get_fingerprint - Given a public key returns the fingerprint.
79  *      @publickey: The key to calculate the id for.
80  *      @fingerprint: The fingerprint (must be at least 20 bytes of space).
81  *      @len: The length of the returned fingerprint.
82  *
83  *      This function returns the fingerprint for a given public key. As Type 3
84  *      fingerprints are 16 bytes and Type 4 are 20 the len field indicates
85  *      which we've returned.
86  */
87 onak_status_t get_fingerprint(struct openpgp_packet *packet,
88         struct openpgp_fingerprint *fingerprint)
89 {
90 #ifdef HAVE_NETTLE
91         struct sha256_ctx sha2_ctx;
92 #endif
93         struct sha1_ctx sha_ctx;
94         struct md5_ctx md5_context;
95         unsigned char c;
96         size_t         modlen, explen;
97
98         if (fingerprint == NULL)
99                 return ONAK_E_INVALID_PARAM;
100
101         fingerprint->length = 0;
102
103         switch (packet->data[0]) {
104         case 2:
105         case 3:
106                 md5_init(&md5_context);
107
108                 /*
109                  * MD5 the modulus and exponent.
110                  */
111                 modlen = ((packet->data[8] << 8) +
112                          packet->data[9] + 7) >> 3;
113                 md5_update(&md5_context, modlen, &packet->data[10]);
114
115                 explen = ((packet->data[10+modlen] << 8) +
116                          packet->data[11+modlen] + 7) >> 3;
117                 md5_update(&md5_context, explen, &packet->data[12 + modlen]);
118
119                 fingerprint->length = 16;
120                 md5_digest(&md5_context, fingerprint->length, fingerprint->fp);
121
122                 break;
123         case 4:
124                 sha1_init(&sha_ctx);
125                 /*
126                  * TODO: Can this be 0x99? Are all public key packets old
127                  * format with 2 bytes of length data?
128                  */
129                 c = 0x99;
130                 sha1_update(&sha_ctx, sizeof(c), &c);
131                 c = packet->length >> 8;
132                 sha1_update(&sha_ctx, sizeof(c), &c);
133                 c = packet->length & 0xFF;
134                 sha1_update(&sha_ctx, sizeof(c), &c);
135                 sha1_update(&sha_ctx, packet->length,
136                         packet->data);
137                 fingerprint->length = 20;
138                 sha1_digest(&sha_ctx, fingerprint->length, fingerprint->fp);
139
140                 break;
141 #ifdef HAVE_NETTLE
142         case 5:
143                 sha256_init(&sha2_ctx);
144                 /* RFC4880bis 12.2 */
145                 c = 0x9A;
146                 sha256_update(&sha2_ctx, sizeof(c), &c);
147                 c = packet->length >> 24;
148                 sha256_update(&sha2_ctx, sizeof(c), &c);
149                 c = packet->length >> 16;
150                 sha256_update(&sha2_ctx, sizeof(c), &c);
151                 c = packet->length >> 8;
152                 sha256_update(&sha2_ctx, sizeof(c), &c);
153                 c = packet->length & 0xFF;
154                 sha256_update(&sha2_ctx, sizeof(c), &c);
155                 sha256_update(&sha2_ctx, packet->length,
156                         packet->data);
157                 fingerprint->length = 32;
158                 sha256_digest(&sha2_ctx, fingerprint->length, fingerprint->fp);
159
160                 break;
161 #endif
162         default:
163                 return ONAK_E_UNKNOWN_VER;
164         }
165
166         return ONAK_E_OK;
167 }
168
169
170 /**
171  *      get_packetid - Given a PGP packet returns the keyid.
172  *      @packet: The packet to calculate the id for.
173  */
174 onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid)
175 {
176         int             offset = 0;
177         int             i = 0;
178         struct openpgp_fingerprint fingerprint;
179 #ifdef NETTLE_WITH_RIPEMD160
180         struct ripemd160_ctx ripemd160_context;
181         uint8_t         data;
182 #endif
183
184         if (packet == NULL || packet->data == NULL)
185                 return ONAK_E_INVALID_PARAM;
186
187         switch (packet->data[0]) {
188         case 2:
189         case 3:
190                 /*
191                  * Old versions of GnuPG would put Elgamal keys inside
192                  * a V3 key structure, then generate the keyid using
193                  * RIPED160.
194                  */
195 #ifdef NETTLE_WITH_RIPEMD160
196                 if (packet->data[7] == 16) {
197                         ripemd160_init(&ripemd160_context);
198                         data = 0x99;
199                         ripemd160_update(&ripemd160_context, 1, &data);
200                         data = packet->length >> 8;
201                         ripemd160_update(&ripemd160_context, 1, &data);
202                         data = packet->length & 0xFF;
203                         ripemd160_update(&ripemd160_context, 1, &data);
204                         ripemd160_update(&ripemd160_context,
205                                 packet->length,
206                                 packet->data);
207
208                         ripemd160_digest(&ripemd160_context,
209                                 RIPEMD160_DIGEST_SIZE,
210                                 fingerprint.fp);
211                         fingerprint.length = RIPEMD160_DIGEST_SIZE;
212
213                         *keyid = fingerprint2keyid(&fingerprint);
214
215                         return ONAK_E_OK;
216                 }
217 #endif
218                 /*
219                  * Check for an RSA key; if not return an error.
220                  * 1 == RSA
221                  * 2 == RSA Encrypt-Only
222                  * 3 == RSA Sign-Only
223                  */
224                 if (packet->data[7] < 1 || packet->data[7] > 3) {
225                         return ONAK_E_INVALID_PKT;
226                 }
227
228                 /*
229                  * For a type 2 or 3 key the keyid is the last 64 bits of the
230                  * public modulus n, which is stored as an MPI from offset 8
231                  * onwards.
232                  */
233                 offset = (packet->data[8] << 8) +
234                         packet->data[9];
235                 offset = ((offset + 7) / 8) + 2;
236
237                 for (*keyid = 0, i = 0; i < 8; i++) {
238                         *keyid <<= 8;
239                         *keyid += packet->data[offset++];
240                 }
241                 break;
242         case 4:
243         case 5:
244                 get_fingerprint(packet, &fingerprint);
245                 *keyid = fingerprint2keyid(&fingerprint);
246                 break;
247         default:
248                 return ONAK_E_UNKNOWN_VER;
249         }
250
251         return ONAK_E_OK;
252 }
253
254 static struct openpgp_packet_list *sortpackets(struct openpgp_packet_list
255                                                         *packets)
256 {
257         struct openpgp_packet_list *sorted, **cur, *next;
258
259         sorted = NULL;
260         while (packets != NULL) {
261                 cur = &sorted;
262                 while (*cur != NULL && compare_packets((*cur)->packet,
263                                 packets->packet) < 0) {
264                         cur = &((*cur)->next);
265                 }
266                 next = *cur;
267                 *cur = packets;
268                 packets = packets->next;
269                 (*cur)->next = next;
270         }
271
272         return sorted;
273 }
274
275 onak_status_t get_skshash(struct openpgp_publickey *key, struct skshash *hash)
276 {
277         struct openpgp_packet_list *packets = NULL, *list_end = NULL;
278         struct openpgp_packet_list *curpacket;
279         struct md5_ctx md5_context;
280         struct openpgp_publickey *next;
281         uint32_t tmp;
282
283         /*
284          * We only want a single key, so clear any link to the next
285          * one for the period during the flatten.
286          */
287         next = key->next;
288         key->next = NULL;
289         flatten_publickey(key, &packets, &list_end);
290         key->next = next;
291         packets = sortpackets(packets);
292
293         md5_init(&md5_context);
294
295         for (curpacket = packets; curpacket != NULL;
296                         curpacket = curpacket->next) {
297                 tmp = htonl(curpacket->packet->tag);
298                 md5_update(&md5_context, sizeof(tmp), (void *) &tmp);
299                 tmp = htonl(curpacket->packet->length);
300                 md5_update(&md5_context, sizeof(tmp), (void *) &tmp);
301                 md5_update(&md5_context,
302                                 curpacket->packet->length,
303                                 curpacket->packet->data);
304         }
305
306         md5_digest(&md5_context, 16, (uint8_t *) &hash->hash);
307         free_packet_list(packets);
308
309         return ONAK_E_OK;
310 }
311
312 uint8_t hexdigit(char c)
313 {
314         if (c >= '0' && c <= '9')
315                 return c - '0';
316         else if (c >= 'a' && c <= 'f')
317                 return c - 'a' + 10;
318         else if (c >= 'A' && c <= 'F')
319                 return c - 'A' + 10;
320         else
321                 return 0;
322 }
323
324 int parse_skshash(char *search, struct skshash *hash)
325 {
326         int i, len;
327
328         len = strlen(search);
329         if (len > 32) {
330                 return 0;
331         }
332
333         for (i = 0; i < len; i += 2) {
334                 hash->hash[i >> 1] = (hexdigit(search[i]) << 4) +
335                                 hexdigit(search[i + 1]);
336         }
337
338         return 1;
339 }