fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / crypto / signature / ksign-parse.c
1 /* parse packet data
2  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/slab.h>
23 #include <asm/errno.h>
24 #include "local.h"
25
26 static inline uint32_t buffer_to_u32(const uint8_t *buffer)
27 {
28         uint32_t a;
29         a =  *buffer << 24;
30         a |= buffer[1] << 16;
31         a |= buffer[2] << 8;
32         a |= buffer[3];
33         return a;
34 }
35
36 static inline uint16_t read_16(const uint8_t **datap)
37 {
38         uint16_t a;
39         a = *(*datap)++ << 8;
40         a |= *(*datap)++;
41         return a;
42 }
43
44 static inline uint32_t read_32(const uint8_t **datap)
45 {
46         uint32_t a;
47         a =  *(*datap)++ << 24;
48         a |= *(*datap)++ << 16;
49         a |= *(*datap)++ << 8;
50         a |= *(*datap)++;
51         return a;
52 }
53
54 void ksign_free_signature(struct ksign_signature *sig)
55 {
56         int i;
57
58         if (sig) {
59                 for (i = 0; i < DSA_NSIG; i++)
60                         mpi_free(sig->data[i]);
61                 kfree(sig->hashed_data);
62                 kfree(sig->unhashed_data);
63                 kfree(sig);
64         }
65 }
66
67 void ksign_free_public_key(struct ksign_public_key *pk)
68 {
69         int i;
70
71         if (pk) {
72                 for (i = 0; i < DSA_NPKEY; i++)
73                         mpi_free(pk->pkey[i]);
74                 kfree(pk);
75         }
76 }
77
78 void ksign_free_user_id(struct ksign_user_id *uid)
79 {
80         kfree(uid);
81 }
82
83 /*
84  *
85  */
86 static void ksign_calc_pk_keyid(struct hash_desc *sha1,
87                                 struct ksign_public_key *pk)
88 {
89         unsigned n;
90         unsigned nb[DSA_NPKEY];
91         unsigned nn[DSA_NPKEY];
92         uint8_t *pp[DSA_NPKEY];
93         uint32_t a32;
94         int i;
95         int npkey = DSA_NPKEY;
96
97         crypto_hash_init(sha1);
98
99         n = pk->version < 4 ? 8 : 6;
100         for (i = 0; i < npkey; i++) {
101                 nb[i] = mpi_get_nbits(pk->pkey[i]);
102                 pp[i] = mpi_get_buffer( pk->pkey[i], nn + i, NULL);
103                 n += 2 + nn[i];
104         }
105
106         SHA1_putc(sha1, 0x99);     /* ctb */
107         SHA1_putc(sha1, n >> 8);   /* 2 uint8_t length header */
108         SHA1_putc(sha1, n);
109
110         if (pk->version < 4)
111                 SHA1_putc(sha1, 3);
112         else
113                 SHA1_putc(sha1, 4);
114
115         a32 = pk->timestamp;
116         SHA1_putc(sha1, a32 >> 24 );
117         SHA1_putc(sha1, a32 >> 16 );
118         SHA1_putc(sha1, a32 >>  8 );
119         SHA1_putc(sha1, a32 >>  0 );
120
121         if (pk->version < 4) {
122                 uint16_t a16;
123
124                 if( pk->expiredate )
125                         a16 = (uint16_t)
126                                 ((pk->expiredate - pk->timestamp) / 86400L);
127                 else
128                         a16 = 0;
129                 SHA1_putc(sha1, a16 >> 8);
130                 SHA1_putc(sha1, a16 >> 0);
131         }
132
133         SHA1_putc(sha1, PUBKEY_ALGO_DSA);
134
135         for (i = 0; i < npkey; i++) {
136                 SHA1_putc(sha1, nb[i] >> 8);
137                 SHA1_putc(sha1, nb[i]);
138                 SHA1_write(sha1, pp[i], nn[i]);
139                 kfree(pp[i]);
140         }
141 }
142
143 /*
144  * parse a user ID embedded in a signature
145  */
146 static int ksign_parse_user_id(const uint8_t *datap, const uint8_t *endp,
147                                ksign_user_id_actor_t uidfnx, void *fnxdata)
148 {
149         struct ksign_user_id *uid;
150         int rc = 0;
151         int n;
152
153         if (!uidfnx)
154                 return 0;
155
156         n = endp - datap;
157         uid = kmalloc(sizeof(*uid) + n + 1, GFP_KERNEL);
158         if (!uid)
159                 return -ENOMEM;
160         uid->len = n;
161
162         memcpy(uid->name, datap, n);
163         uid->name[n] = 0;
164
165         rc = uidfnx(uid, fnxdata);
166         if (rc == 0)
167                 return rc; /* uidfnx keeps the record */
168         if (rc == 1)
169                 rc = 0;
170
171         ksign_free_user_id(uid);
172         return rc;
173 }
174
175 /*
176  * extract a public key embedded in a signature
177  */
178 static int ksign_parse_key(const uint8_t *datap, const uint8_t *endp,
179                            uint8_t *hdr, int hdrlen,
180                            ksign_public_key_actor_t pkfnx, void *fnxdata)
181 {
182         struct ksign_public_key *pk;
183         struct hash_desc sha1;
184         unsigned long timestamp, expiredate;
185         uint8_t hash[SHA1_DIGEST_SIZE];
186         int i, version;
187         int is_v4 = 0;
188         int rc = 0;
189
190         if (endp - datap < 12) {
191                 printk("ksign: public key packet too short\n");
192                 return -EBADMSG;
193         }
194
195         version = *datap++;
196         switch (version) {
197         case 4:
198                 is_v4 = 1;
199         case 2:
200         case 3:
201                 break;
202         default:
203                 printk("ksign: public key packet with unknown version %d\n",
204                        version);
205                 return -EBADMSG;
206         }
207
208         timestamp = read_32(&datap);
209         if (is_v4) {
210                 expiredate = 0; /* have to get it from the selfsignature */
211         } else {
212                 unsigned short ndays;
213                 ndays = read_16(&datap);
214                 if (ndays)
215                         expiredate = timestamp + ndays * 86400L;
216                 else
217                         expiredate = 0;
218         }
219
220         if (*datap++ != PUBKEY_ALGO_DSA) {
221                 printk("ksign: public key packet with unknown version %d\n",
222                        version);
223                 return 0;
224         }
225
226         /* extract the stuff from the DSA public key */
227         pk = kzalloc(sizeof(struct ksign_public_key), GFP_KERNEL);
228         if (!pk)
229                 return -ENOMEM;
230
231         atomic_set(&pk->count, 1);
232         pk->timestamp   = timestamp;
233         pk->expiredate  = expiredate;
234         pk->hdrbytes    = hdrlen;
235         pk->version     = version;
236
237         for (i = 0; i < DSA_NPKEY; i++) {
238                 unsigned int remaining = endp - datap;
239                 pk->pkey[i] = mpi_read_from_buffer(datap, &remaining);
240                 datap += remaining;
241         }
242
243         rc = -ENOMEM;
244
245         sha1.tfm = crypto_hash_cast(crypto_alloc_tfm2("sha1", 0, 1));
246         if (!sha1.tfm)
247                 goto cleanup;
248         sha1.flags = 0;
249
250         ksign_calc_pk_keyid(&sha1, pk);
251         crypto_hash_final(&sha1, hash);
252         crypto_free_hash(sha1.tfm);
253
254         pk->keyid[0] = hash[12] << 24 | hash[13] << 16 | hash[14] << 8 | hash[15];
255         pk->keyid[1] = hash[16] << 24 | hash[17] << 16 | hash[18] << 8 | hash[19];
256
257         rc = 0;
258         if (pkfnx)
259                 rc = pkfnx(pk, fnxdata);
260
261 cleanup:
262         ksign_put_public_key(pk);
263         return rc;
264 }
265
266 /*
267  * find an element representing the issuer
268  */
269 static const uint8_t *ksign_find_sig_issuer(const uint8_t *buffer)
270 {
271         size_t buflen;
272         size_t n;
273         int type;
274         int seq = 0;
275
276         if (!buffer)
277                 return NULL;
278
279         buflen = read_16(&buffer);
280         while (buflen) {
281                 n = *buffer++; buflen--;
282                 if (n == 255) {
283                         if (buflen < 4)
284                                 goto too_short;
285                         n = read_32(&buffer);
286                         buflen -= 4;
287                 } else if (n >= 192) {
288                         if(buflen < 2)
289                                 goto too_short;
290                         n = ((n - 192) << 8) + *buffer + 192;
291                         buffer++;
292                         buflen--;
293                 }
294
295                 if (buflen < n)
296                         goto too_short;
297
298                 type = *buffer & 0x7f;
299                 if (!(++seq > 0)) {
300                         ;
301                 } else if (type == SIGSUBPKT_ISSUER) {
302                         /* found */
303                         buffer++;
304                         n--;
305                         if (n > buflen || n < 8)
306                                 goto too_short;
307                         return buffer;
308                 }
309
310                 buffer += n;
311                 buflen -= n;
312         }
313
314 too_short:
315         return NULL; /* end of subpackets; not found */
316 }
317
318 /*
319  * extract signature data embedded in a signature
320  */
321 static int ksign_parse_signature(const uint8_t *datap, const uint8_t *endp,
322                                  ksign_signature_actor_t sigfnx, void *fnxdata)
323 {
324         struct ksign_signature *sig;
325         size_t n;
326         int version, is_v4 = 0;
327         int rc;
328         int i;
329
330         if (endp - datap < 16) {
331                 printk("ksign: signature packet too short\n");
332                 return -EBADMSG;
333         }
334
335         version = *datap++;
336         switch (version) {
337         case 4:
338                 is_v4 = 1;
339         case 3:
340         case 2:
341                 break;
342         default:
343                 printk("ksign: signature packet with unknown version %d\n",
344                        version);
345                 return 0;
346         }
347
348         /* store information */
349         sig = kzalloc(sizeof(*sig), GFP_KERNEL);
350         if (!sig)
351                 return -ENOMEM;
352
353         sig->version = version;
354
355         if (!is_v4)
356                 datap++; /* ignore md5 length */
357
358         sig->sig_class = *datap++;
359         if (!is_v4) {
360                 sig->timestamp = read_32(&datap);
361                 sig->keyid[0] = read_32(&datap);
362                 sig->keyid[1] = read_32(&datap);
363         }
364
365         rc = 0;
366         if (*datap++ != PUBKEY_ALGO_DSA) {
367                 printk("ksign: ignoring non-DSA signature\n");
368                 goto leave;
369         }
370         if (*datap++ != DIGEST_ALGO_SHA1) {
371                 printk("ksign: ignoring non-SHA1 signature\n");
372                 goto leave;
373         }
374
375         rc = -EBADMSG;
376         if (is_v4) {
377                 /* read subpackets */
378                 n = read_16(&datap); /* length of hashed data */
379                 if (n > 10000) {
380                         printk("ksign: signature packet:"
381                                " hashed data too long\n");
382                         goto leave;
383                 }
384                 if (n) {
385                         if ((size_t)(endp - datap) < n) {
386                                 printk("ksign: signature packet:"
387                                        " available data too short\n");
388                                 goto leave;
389                         }
390                         sig->hashed_data = kmalloc(n + 2, GFP_KERNEL);
391                         if (!sig->hashed_data) {
392                                 rc = -ENOMEM;
393                                 goto leave;
394                         }
395                         sig->hashed_data[0] = n >> 8;
396                         sig->hashed_data[1] = n;
397                         memcpy(sig->hashed_data + 2, datap, n);
398                         datap += n;
399                 }
400
401                 n = read_16(&datap); /* length of unhashed data */
402                 if (n > 10000) {
403                         printk("ksign: signature packet:"
404                                " unhashed data too long\n");
405                         goto leave;
406                 }
407                 if (n) {
408                         if ((size_t) (endp - datap) < n) {
409                                 printk("ksign: signature packet:"
410                                        " available data too short\n");
411                                 goto leave;
412                         }
413                         sig->unhashed_data = kmalloc(n + 2, GFP_KERNEL);
414                         if (!sig->unhashed_data) {
415                                 rc = -ENOMEM;
416                                 goto leave;
417                         }
418                         sig->unhashed_data[0] = n >> 8;
419                         sig->unhashed_data[1] = n;
420                         memcpy(sig->unhashed_data + 2, datap, n);
421                         datap += n;
422                 }
423         }
424
425         if (endp - datap < 5) { /* sanity check */
426                 printk("ksign: signature packet too short\n");
427                 goto leave;
428         }
429
430         sig->digest_start[0] = *datap++;
431         sig->digest_start[1] = *datap++;
432
433         if (is_v4) {
434                 const uint8_t *p;
435
436                 p = ksign_find_sig_issuer(sig->hashed_data);
437                 if (!p)
438                         p = ksign_find_sig_issuer(sig->unhashed_data);
439                 if (!p) {
440                         printk("ksign: signature packet without issuer\n");
441                 } else {
442                         sig->keyid[0] = buffer_to_u32(p);
443                         sig->keyid[1] = buffer_to_u32(p + 4);
444                 }
445         }
446
447         for (i = 0; i < DSA_NSIG; i++) {
448                 unsigned remaining = endp - datap;
449                 sig->data[i] = mpi_read_from_buffer(datap, &remaining);
450                 datap += remaining;
451         }
452
453         rc = 0;
454         if (sigfnx) {
455                 rc = sigfnx(sig, fnxdata);
456                 if (rc == 0)
457                         return rc; /* sigfnx keeps the signature */
458                 if (rc == 1)
459                         rc = 0;
460         }
461
462 leave:
463         ksign_free_signature(sig);
464         return rc;
465 }
466
467 /*
468  * parse the next packet and call appropriate handler function for known types
469  * - returns:
470  *     0 on EOF
471  *     1 if there might be more packets
472  *     -EBADMSG if the packet is in an invalid format
473  *     -ve on other error
474  */
475 static int ksign_parse_one_packet(const uint8_t **datap,
476                                   const uint8_t *endp,
477                                   ksign_signature_actor_t sigfnx,
478                                   ksign_public_key_actor_t pkfnx,
479                                   ksign_user_id_actor_t uidfnx,
480                                   void *data)
481 {
482         int rc, c, ctb, pkttype, lenuint8_ts;
483         unsigned long pktlen;
484         uint8_t hdr[8];
485         int hdrlen;
486
487         /* extract the next packet and dispatch it */
488         rc = 0;
489         if (*datap >= endp)
490                 goto leave;
491         ctb = *(*datap)++;
492
493         rc = -EBADMSG;
494
495         hdrlen = 0;
496         hdr[hdrlen++] = ctb;
497         if (!(ctb & 0x80)) {
498                 printk("ksign: invalid packet (ctb=%02x)\n", ctb);
499                 goto leave;
500         }
501
502         pktlen = 0;
503         if (ctb & 0x40) {
504                 pkttype = ctb & 0x3f;
505                 if (*datap >= endp) {
506                         printk("ksign: 1st length byte missing\n");
507                         goto leave;
508                 }
509                 c = *(*datap)++;
510                 hdr[hdrlen++] = c;
511
512                 if (c < 192) {
513                         pktlen = c;
514                 } else if (c < 224) {
515                         pktlen = (c - 192) * 256;
516                         if (*datap >= endp) {
517                                 printk("ksign: 2nd length uint8_t missing\n");
518                                 goto leave;
519                         }
520                         c = *(*datap)++;
521                         hdr[hdrlen++] = c;
522                         pktlen += c + 192;
523                 } else if (c == 255) {
524                         if (*datap + 3 >= endp) {
525                                 printk("ksign: 4 uint8_t length invalid\n");
526                                 goto leave;
527                         }
528                         pktlen  = (hdr[hdrlen++] = *(*datap)++ << 24);
529                         pktlen |= (hdr[hdrlen++] = *(*datap)++ << 16);
530                         pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  8);
531                         pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  0);
532                 } else {
533                         pktlen = 0;/* to indicate partial length */
534                 }
535         } else {
536                 pkttype = (ctb >> 2) & 0xf;
537                 lenuint8_ts = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3));
538                 if( !lenuint8_ts ) {
539                         pktlen = 0; /* don't know the value */
540                 } else {
541                         if (*datap + lenuint8_ts > endp) {
542                                 printk("ksign: length uint8_ts missing\n");
543                                 goto leave;
544                         }
545                         for( ; lenuint8_ts; lenuint8_ts-- ) {
546                                 pktlen <<= 8;
547                                 pktlen |= hdr[hdrlen++] = *(*datap)++;
548                         }
549                 }
550         }
551
552         if (*datap + pktlen > endp) {
553                 printk("ksign: packet length longer than available data\n");
554                 goto leave;
555         }
556
557         /* deal with the next packet appropriately */
558         switch (pkttype) {
559         case PKT_PUBLIC_KEY:
560                 rc = ksign_parse_key(*datap, *datap + pktlen, hdr, hdrlen,
561                                      pkfnx, data);
562                 break;
563         case PKT_SIGNATURE:
564                 rc = ksign_parse_signature(*datap, *datap + pktlen,
565                                            sigfnx, data);
566                 break;
567         case PKT_USER_ID:
568                 rc = ksign_parse_user_id(*datap, *datap + pktlen,
569                                          uidfnx, data);
570                 break;
571         default:
572                 rc = 0; /* unknown packet */
573                 break;
574         }
575
576         *datap += pktlen;
577 leave:
578         return rc;
579 }
580
581 /*
582  * parse the contents of a packet buffer, passing the signature, public key and
583  * user ID to the caller's callback functions
584  */
585 int ksign_parse_packets(const uint8_t *buf,
586                         size_t size,
587                         ksign_signature_actor_t sigfnx,
588                         ksign_public_key_actor_t pkfnx,
589                         ksign_user_id_actor_t uidfnx,
590                         void *data)
591 {
592         const uint8_t *datap, *endp;
593         int rc;
594
595         datap = buf;
596         endp = buf + size;
597         do {
598                 rc = ksign_parse_one_packet(&datap, endp,
599                                             sigfnx, pkfnx, uidfnx, data);
600         } while (rc == 0 && datap < endp);
601
602         return rc;
603 }