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