]> the.earth.li Git - onak.git/blob - keyid.c
Set Rules-Requires-Root to no
[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         struct sha256_ctx sha2_ctx;
91         struct sha1_ctx sha_ctx;
92         struct md5_ctx md5_context;
93         unsigned char c;
94         size_t         modlen, explen;
95
96         if (fingerprint == NULL)
97                 return ONAK_E_INVALID_PARAM;
98
99         fingerprint->length = 0;
100
101         switch (packet->data[0]) {
102         case 2:
103         case 3:
104                 md5_init(&md5_context);
105
106                 /*
107                  * MD5 the modulus and exponent.
108                  */
109                 modlen = ((packet->data[8] << 8) +
110                          packet->data[9] + 7) >> 3;
111                 md5_update(&md5_context, modlen, &packet->data[10]);
112
113                 explen = ((packet->data[10+modlen] << 8) +
114                          packet->data[11+modlen] + 7) >> 3;
115                 md5_update(&md5_context, explen, &packet->data[12 + modlen]);
116
117                 fingerprint->length = 16;
118                 md5_digest(&md5_context, fingerprint->length, fingerprint->fp);
119
120                 break;
121         case 4:
122                 sha1_init(&sha_ctx);
123                 /*
124                  * TODO: Can this be 0x99? Are all public key packets old
125                  * format with 2 bytes of length data?
126                  */
127                 c = 0x99;
128                 sha1_update(&sha_ctx, sizeof(c), &c);
129                 c = packet->length >> 8;
130                 sha1_update(&sha_ctx, sizeof(c), &c);
131                 c = packet->length & 0xFF;
132                 sha1_update(&sha_ctx, sizeof(c), &c);
133                 sha1_update(&sha_ctx, packet->length,
134                         packet->data);
135                 fingerprint->length = 20;
136                 sha1_digest(&sha_ctx, fingerprint->length, fingerprint->fp);
137
138                 break;
139         case 5:
140                 sha256_init(&sha2_ctx);
141                 /* RFC4880bis 12.2 */
142                 c = 0x9A;
143                 sha256_update(&sha2_ctx, sizeof(c), &c);
144                 c = packet->length >> 24;
145                 sha256_update(&sha2_ctx, sizeof(c), &c);
146                 c = packet->length >> 16;
147                 sha256_update(&sha2_ctx, sizeof(c), &c);
148                 c = packet->length >> 8;
149                 sha256_update(&sha2_ctx, sizeof(c), &c);
150                 c = packet->length & 0xFF;
151                 sha256_update(&sha2_ctx, sizeof(c), &c);
152                 sha256_update(&sha2_ctx, packet->length,
153                         packet->data);
154                 fingerprint->length = 32;
155                 sha256_digest(&sha2_ctx, fingerprint->length, fingerprint->fp);
156
157                 break;
158         default:
159                 return ONAK_E_UNKNOWN_VER;
160         }
161
162         return ONAK_E_OK;
163 }
164
165
166 /**
167  *      get_packetid - Given a PGP packet returns the keyid.
168  *      @packet: The packet to calculate the id for.
169  */
170 onak_status_t get_packetid(struct openpgp_packet *packet, uint64_t *keyid)
171 {
172         int             offset = 0;
173         int             i = 0;
174         struct openpgp_fingerprint fingerprint;
175 #ifdef NETTLE_WITH_RIPEMD160
176         struct ripemd160_ctx ripemd160_context;
177         uint8_t         data;
178 #endif
179
180         if (packet == NULL || packet->data == NULL)
181                 return ONAK_E_INVALID_PARAM;
182
183         switch (packet->data[0]) {
184         case 2:
185         case 3:
186                 /*
187                  * Old versions of GnuPG would put Elgamal keys inside
188                  * a V3 key structure, then generate the keyid using
189                  * RIPED160.
190                  */
191 #ifdef NETTLE_WITH_RIPEMD160
192                 if (packet->data[7] == 16) {
193                         ripemd160_init(&ripemd160_context);
194                         data = 0x99;
195                         ripemd160_update(&ripemd160_context, 1, &data);
196                         data = packet->length >> 8;
197                         ripemd160_update(&ripemd160_context, 1, &data);
198                         data = packet->length & 0xFF;
199                         ripemd160_update(&ripemd160_context, 1, &data);
200                         ripemd160_update(&ripemd160_context,
201                                 packet->length,
202                                 packet->data);
203
204                         ripemd160_digest(&ripemd160_context,
205                                 RIPEMD160_DIGEST_SIZE,
206                                 fingerprint.fp);
207                         fingerprint.length = RIPEMD160_DIGEST_SIZE;
208
209                         *keyid = fingerprint2keyid(&fingerprint);
210
211                         return ONAK_E_OK;
212                 }
213 #endif
214                 /*
215                  * Check for an RSA key; if not return an error.
216                  * 1 == RSA
217                  * 2 == RSA Encrypt-Only
218                  * 3 == RSA Sign-Only
219                  */
220                 if (packet->data[7] < 1 || packet->data[7] > 3) {
221                         return ONAK_E_INVALID_PKT;
222                 }
223
224                 /*
225                  * For a type 2 or 3 key the keyid is the last 64 bits of the
226                  * public modulus n, which is stored as an MPI from offset 8
227                  * onwards.
228                  */
229                 offset = (packet->data[8] << 8) +
230                         packet->data[9];
231                 offset = ((offset + 7) / 8) + 2;
232
233                 for (*keyid = 0, i = 0; i < 8; i++) {
234                         *keyid <<= 8;
235                         *keyid += packet->data[offset++];
236                 }
237                 break;
238         case 4:
239         case 5:
240                 get_fingerprint(packet, &fingerprint);
241                 *keyid = fingerprint2keyid(&fingerprint);
242                 break;
243         default:
244                 return ONAK_E_UNKNOWN_VER;
245         }
246
247         return ONAK_E_OK;
248 }
249
250 static struct openpgp_packet_list *sortpackets(struct openpgp_packet_list
251                                                         *packets)
252 {
253         struct openpgp_packet_list *sorted, **cur, *next;
254
255         sorted = NULL;
256         while (packets != NULL) {
257                 cur = &sorted;
258                 while (*cur != NULL && compare_packets((*cur)->packet,
259                                 packets->packet) < 0) {
260                         cur = &((*cur)->next);
261                 }
262                 next = *cur;
263                 *cur = packets;
264                 packets = packets->next;
265                 (*cur)->next = next;
266         }
267
268         return sorted;
269 }
270
271 onak_status_t get_skshash(struct openpgp_publickey *key, struct skshash *hash)
272 {
273         struct openpgp_packet_list *packets = NULL, *list_end = NULL;
274         struct openpgp_packet_list *curpacket;
275         struct md5_ctx md5_context;
276         struct openpgp_publickey *next;
277         uint32_t tmp;
278
279         /*
280          * We only want a single key, so clear any link to the next
281          * one for the period during the flatten.
282          */
283         next = key->next;
284         key->next = NULL;
285         flatten_publickey(key, &packets, &list_end);
286         key->next = next;
287         packets = sortpackets(packets);
288
289         md5_init(&md5_context);
290
291         for (curpacket = packets; curpacket != NULL;
292                         curpacket = curpacket->next) {
293                 tmp = htonl(curpacket->packet->tag);
294                 md5_update(&md5_context, sizeof(tmp), (void *) &tmp);
295                 tmp = htonl(curpacket->packet->length);
296                 md5_update(&md5_context, sizeof(tmp), (void *) &tmp);
297                 md5_update(&md5_context,
298                                 curpacket->packet->length,
299                                 curpacket->packet->data);
300         }
301
302         md5_digest(&md5_context, 16, (uint8_t *) &hash->hash);
303         free_packet_list(packets);
304
305         return ONAK_E_OK;
306 }
307
308 uint8_t hexdigit(char c)
309 {
310         if (c >= '0' && c <= '9')
311                 return c - '0';
312         else if (c >= 'a' && c <= 'f')
313                 return c - 'a' + 10;
314         else if (c >= 'A' && c <= 'F')
315                 return c - 'A' + 10;
316         else
317                 return 0;
318 }
319
320 int parse_skshash(char *search, struct skshash *hash)
321 {
322         int i, len;
323
324         len = strlen(search);
325         if (len > 32) {
326                 return 0;
327         }
328
329         for (i = 0; i < len; i += 2) {
330                 hash->hash[i >> 1] = (hexdigit(search[i]) << 4) +
331                                 hexdigit(search[i + 1]);
332         }
333
334         return 1;
335 }