Added OpenPGP library to lib/silcpgp
[crypto.git] / lib / silcpgp / silcpgp.c
1 /*
2
3   silcpgp.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2007 - 2008 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silccrypto.h"
21
22 /************************* Static utility functions *************************/
23
24 /* Parse PGP packet */
25
26 static int
27 silc_pgp_packet_parse(const unsigned char *data, SilcUInt32 data_len,
28                       SilcPGPPacket *ret_packet)
29 {
30   SilcPGPPacket packet;
31   SilcBufferStruct buf;
32   SilcUInt8 tag;
33   SilcBool partial = FALSE;
34   SilcUInt32 len;
35
36   SILC_LOG_DEBUG(("Parsing OpenPGP packet"));
37
38   if (!data || data_len < 2)
39     return 0;
40   silc_buffer_set(&buf, (unsigned char *)data, data_len);
41
42   packet = silc_calloc(1, sizeof(*packet));
43   if (!packet)
44     return 0;
45
46   while (silc_buffer_len(&buf) > 0) {
47     tag = buf.data[0];
48     silc_buffer_pull(&buf, 1);
49
50     if (!(tag & 0x80)) {
51       SILC_LOG_DEBUG(("Invalid tag"));
52       goto err;
53     }
54
55     if (tag & 0x40) {
56       /* New format */
57
58       /* Packet type */
59       if (!packet->tag) {
60         packet->tag = tag & 0x3f;
61         SILC_LOG_DEBUG(("Packet type %d (%s)", packet->tag,
62                         silc_pgp_packet_name(packet->tag)));
63       }
64
65       /* Packet length */
66       len = buf.data[0];
67       if (len >= 192 && len <= 223) {
68         /* 2 byte length */
69         if (silc_buffer_len(&buf) < 2)
70           goto err;
71         len = ((len - 192) << 8) + buf.data[1] + 192;
72         silc_buffer_pull(&buf, 2);
73       } else if (len == 255) {
74         /* 5 byte length */
75         if (silc_buffer_len(&buf) < 5)
76           goto err;
77         silc_buffer_pull(&buf, 1);
78         SILC_GET32_MSB(len, buf.data);
79         silc_buffer_pull(&buf, 4);
80       } else if (len >= 224 && len < 255) {
81         /* Partial length */
82         if (silc_buffer_len(&buf) < 1)
83           goto err;
84         len = 1 << (len & 0x1f);
85         silc_buffer_pull(&buf, 1);
86         partial = TRUE;
87       }
88     } else {
89       /* Old format */
90       SilcUInt8 llen;
91
92       /* Pakcet type */
93       if (!packet->tag) {
94         packet->tag = (tag >> 2) & 0x0f;
95         SILC_LOG_DEBUG(("Packet type %d (%s)", packet->tag,
96                         silc_pgp_packet_name(packet->tag)));
97       }
98
99       if ((tag & 0x03) == 3) {
100         /* Indeterminate length, use whole buffer */
101         len = silc_buffer_len(&buf);
102       } else {
103         for (llen = 1 << (tag & 0x03), len = 0 ; llen; llen--) {
104           len <<= 8;
105           len |= buf.data[0];
106           if (!silc_buffer_pull(&buf, 1))
107             goto err;
108         }
109       }
110     }
111
112     if (silc_buffer_len(&buf) < len) {
113       SILC_LOG_DEBUG(("Too short packet (%d < %d)",
114                       silc_buffer_len(&buf), len));
115       goto err;
116     }
117
118     /* Get data */
119     if (silc_buffer_format(&packet->data,
120                            SILC_STR_ADVANCE,
121                            SILC_STR_DATA(silc_buffer_data(&buf), len),
122                            SILC_STR_END) < 0)
123       goto err;
124
125     silc_buffer_pull(&buf, len);
126
127     if (!partial)
128       break;
129   }
130
131   silc_buffer_start(&packet->data);
132
133   SILC_LOG_HEXDUMP(("Packet, len %d", silc_buffer_len(&packet->data)),
134                     silc_buffer_data(&packet->data),
135                     silc_buffer_len(&packet->data));
136
137   *ret_packet = packet;
138
139   return silc_buffer_headlen(&buf);
140
141  err:
142   silc_buffer_purge(&packet->data);
143   silc_free(packet);
144   return 0;
145 }
146
147 /****************************** PGP Algorithms ******************************/
148
149 /* Allocates cipher */
150
151 SilcCipher silc_pgp_cipher_alloc(SilcPGPCipher cipher)
152 {
153   SilcCipher c;
154
155   SILC_LOG_DEBUG(("Allocate cipher %d", cipher));
156
157   switch (cipher) {
158   case SILC_PGP_CIPHER_IDEA:
159     if (!silc_cipher_alloc("idea-128-cfb", &c)) {
160       SILC_LOG_ERROR(("Unsupported algorithm idea-128-cfb"));
161       return NULL;
162     }
163     break;
164
165   case SILC_PGP_CIPHER_3DES:
166     if (!silc_cipher_alloc("3des-168-cfb", &c)) {
167       SILC_LOG_ERROR(("Unsupported algorithm 3des-168-cfb"));
168       return NULL;
169     }
170     break;
171
172   case SILC_PGP_CIPHER_CAST5:
173     if (!silc_cipher_alloc("cast5-128-cfb", &c)) {
174       SILC_LOG_ERROR(("Unsupported algorithm cast5-168-cfb"));
175       return NULL;
176     }
177     break;
178
179   case SILC_PGP_CIPHER_BLOWFISH:
180     if (!silc_cipher_alloc("blowfish-128-cfb", &c)) {
181       SILC_LOG_ERROR(("Unsupported algorithm blowfish-128-cfb"));
182       return NULL;
183     }
184     break;
185
186   case SILC_PGP_CIPHER_AES128:
187     if (!silc_cipher_alloc("aes-128-cfb", &c)) {
188       SILC_LOG_ERROR(("Unsupported algorithm aes-128-cfb"));
189       return NULL;
190     }
191     break;
192
193   case SILC_PGP_CIPHER_AES192:
194     if (!silc_cipher_alloc("aes-192-cfb", &c)) {
195       SILC_LOG_ERROR(("Unsupported algorithm aes-192-cfb"));
196       return NULL;
197     }
198     break;
199
200   case SILC_PGP_CIPHER_AES256:
201     if (!silc_cipher_alloc("aes-256-cfb", &c)) {
202       SILC_LOG_ERROR(("Unsupported algorithm aes-256-cfb"));
203       return NULL;
204     }
205     break;
206
207   case SILC_PGP_CIPHER_TWOFISH:
208     if (!silc_cipher_alloc("twofish-256-cfb", &c)) {
209       SILC_LOG_ERROR(("Unsupported algorithm twofish-256-cfb"));
210       return NULL;
211     }
212     break;
213
214   default:
215     return NULL;
216     break;
217   }
218
219   return c;
220 }
221
222 /* Allocates hash function */
223
224 SilcHash silc_pgp_hash_alloc(SilcPGPHash hash)
225 {
226   SilcHash h;
227
228   SILC_LOG_DEBUG(("Allocate hash %d", hash));
229
230   switch (hash) {
231   case SILC_PGP_HASH_MD5:
232     if (!silc_hash_alloc("md5", &h)) {
233       SILC_LOG_ERROR(("Unsupported algorithm md5"));
234       return NULL;
235     }
236     break;
237
238   case SILC_PGP_HASH_SHA1:
239     if (!silc_hash_alloc("sha1", &h)) {
240       SILC_LOG_ERROR(("Unsupported algorithm sha1"));
241       return NULL;
242     }
243     break;
244
245   case SILC_PGP_HASH_RIPEMD160:
246     if (!silc_hash_alloc("ripemd160", &h)) {
247       SILC_LOG_ERROR(("Unsupported algorithm ripemd160"));
248       return NULL;
249     }
250     break;
251
252   case SILC_PGP_HASH_SHA256:
253     if (!silc_hash_alloc("sha256", &h)) {
254       SILC_LOG_ERROR(("Unsupported algorithm sha256"));
255       return NULL;
256     }
257     break;
258
259   case SILC_PGP_HASH_SHA384:
260     if (!silc_hash_alloc("sha384", &h)) {
261       SILC_LOG_ERROR(("Unsupported algorithm sha384"));
262       return NULL;
263     }
264     break;
265
266   case SILC_PGP_HASH_SHA512:
267     if (!silc_hash_alloc("sha512", &h)) {
268       SILC_LOG_ERROR(("Unsupported algorithm sha512"));
269       return NULL;
270     }
271     break;
272
273   case SILC_PGP_HASH_SHA224:
274     if (!silc_hash_alloc("sha244", &h)) {
275       SILC_LOG_ERROR(("Unsupported algorithm sha224"));
276       return NULL;
277     }
278     break;
279
280   default:
281     return NULL;
282     break;
283   }
284
285   return h;
286 }
287
288 /************************* OpenPGP Packet routines **************************/
289
290 #ifdef SILC_DEBUG
291 /* Return packet tag as string */
292
293 const char *silc_pgp_packet_name(SilcPGPPacketTag tag)
294 {
295   if (tag == SILC_PGP_PACKET_PKENC_SK)
296     return "PKENC_SK";
297   if (tag == SILC_PGP_PACKET_SIGNATURE)
298     return "SIGNATURE";
299   if (tag == SILC_PGP_PACKET_SENC_SK)
300     return "SENC_SK";
301   if (tag == SILC_PGP_PACKET_OP_SIGNATURE)
302     return "OP_SIGNATUER";
303   if (tag == SILC_PGP_PACKET_SECKEY)
304     return "SECKEY";
305   if (tag == SILC_PGP_PACKET_PUBKEY)
306     return "PUBKEY";
307   if (tag == SILC_PGP_PACKET_SECKEY_SUB)
308     return "SECKEY_SUB";
309   if (tag == SILC_PGP_PACKET_COMP_DATA)
310     return "COMP_DATA";
311   if (tag == SILC_PGP_PACKET_SENC_DATA)
312     return "SENC_DATA";
313   if (tag == SILC_PGP_PACKET_MARKER)
314     return "MARKER";
315   if (tag == SILC_PGP_PACKET_LITERAL_DATA)
316     return "LITERAL_DATA";
317   if (tag == SILC_PGP_PACKET_TRUST)
318     return "TRUST";
319   if (tag == SILC_PGP_PACKET_USER_ID)
320     return "USER_ID";
321   if (tag == SILC_PGP_PACKET_PUBKEY_SUB)
322     return "PUBKEY_SUB";
323   if (tag == SILC_PGP_PACKET_USER_ATTR)
324     return "USER_ATTR";
325   if (tag == SILC_PGP_PACKET_SENC_I_DATA)
326     return "SENC_I_DATA";
327   if (tag == SILC_PGP_PACKET_MDC)
328     return "MDC";
329   return "UNKNOWN";
330 }
331 #endif /* SILC_DEBUG */
332
333 /* Copy packet */
334
335 SilcPGPPacket silc_pgp_packet_copy(SilcPGPPacket packet)
336 {
337   SilcPGPPacket newpacket;
338   unsigned char *data;
339
340   newpacket = silc_calloc(1, sizeof(*newpacket));
341   if (!newpacket)
342     return NULL;
343
344   data = silc_memdup(packet->data.head, silc_buffer_truelen(&packet->data));
345   if (!data) {
346     silc_free(newpacket);
347     return NULL;
348   }
349
350   silc_buffer_set(&newpacket->data, data, silc_buffer_truelen(&packet->data));
351   newpacket->tag = packet->tag;
352
353   return newpacket;
354 }
355
356 /* Decode all PGP packets into a list */
357
358 int silc_pgp_packet_decode(const unsigned char *data,
359                            SilcUInt32 data_len,
360                            SilcBool *success,
361                            SilcList *ret_list)
362 {
363   SilcBufferStruct buf;
364   SilcPGPPacket packet;
365   int ret;
366
367   SILC_LOG_DEBUG(("Parsing OpenPGP packets"));
368
369   if (success)
370     *success = TRUE;
371
372   if (!data || data_len < 2)
373     return 0;
374
375   silc_buffer_set(&buf, (unsigned char *)data, data_len);
376   silc_list_init(*ret_list, struct SilcPGPPacketStruct, next);
377
378   /* Parse one by one */
379   while (silc_buffer_len(&buf) > 0) {
380     ret = silc_pgp_packet_parse(silc_buffer_data(&buf),
381                                 silc_buffer_len(&buf), &packet);
382     if (!ret) {
383       if (success)
384         *success = FALSE;
385       break;
386     }
387
388     silc_buffer_pull(&buf, ret);
389     silc_list_add(*ret_list, packet);
390   }
391
392   SILC_LOG_DEBUG(("Parsed %d packets", silc_list_count(*ret_list)));
393
394   silc_list_start(*ret_list);
395
396   return silc_list_count(*ret_list);
397 }
398
399 /* Get PGP packet tag (packet type) */
400
401 SilcPGPPacketTag silc_pgp_packet_get_tag(SilcPGPPacket packet)
402 {
403   return packet->tag;
404 }
405
406 /* Get PGP packet data */
407
408 unsigned char *silc_pgp_packet_get_data(SilcPGPPacket packet,
409                                         SilcUInt32 *data_len)
410 {
411   unsigned char *ptr = silc_buffer_data(&packet->data);
412   if (data_len)
413     *data_len = silc_buffer_len(&packet->data);
414   return ptr;
415 }
416
417 /* Free PGP packet from  */
418
419 void silc_pgp_packet_free(SilcPGPPacket packet)
420 {
421   silc_buffer_purge(&packet->data);
422   silc_free(packet);
423 }
424
425 /* Free PGP packets from list */
426
427 void silc_pgp_packet_free_list(SilcList *list)
428 {
429   SilcPGPPacket packet;
430
431   silc_list_start(*list);
432   while ((packet = silc_list_get(*list))) {
433     silc_buffer_purge(&packet->data);
434     silc_free(packet);
435   }
436 }
437
438 /****************************** String to Key *******************************/
439
440 /* PGP String-to-key.  Converts passphrases to encryption and decryption
441    keys.  This can be used to create both encryption and decryption key. */
442
443 unsigned char *silc_pgp_s2k(SilcPGPS2KType type,
444                             SilcPGPHash hash,
445                             const char *passphrase,
446                             SilcUInt32 passphrase_len,
447                             SilcUInt32 key_len,
448                             unsigned char *salt,
449                             SilcUInt32 iter_octet_count,
450                             SilcRng rng)
451 {
452   SilcHash h = NULL;
453   unsigned char *key = NULL, digest[SILC_HASH_MAXLEN], preload[8], esalt[8];
454   SilcUInt32 hash_len;
455   int i, k;
456
457   if (!passphrase)
458     return NULL;
459
460   SILC_LOG_DEBUG(("Compute S2K for %s", salt ? "decryption" : "encryption"));
461
462   h = silc_pgp_hash_alloc(hash);
463   if (!h)
464     return NULL;
465   hash_len = silc_hash_len(h);
466
467   key = silc_malloc(key_len);
468   if (!key)
469     goto err;
470
471   memset(preload, 0, sizeof(preload));
472   silc_hash_init(h);
473
474   /* If salt is NULL, we'll create one for encryption */
475   if (!salt) {
476     silc_rng_get_rn_data(rng, 8, esalt, sizeof(esalt));
477     salt = esalt;
478   }
479
480   switch (type) {
481   case SILC_PGP_S2K_SIMPLE:
482     /* Hash passphrase */
483     for (i = 0; i < key_len; i += hash_len) {
484       if (i && i < sizeof(preload)) {
485         silc_hash_init(h);
486         silc_hash_update(h, preload, i);
487       }
488
489       silc_hash_update(h, passphrase, passphrase_len);
490       silc_hash_final(h, digest);
491       memcpy(key + i, digest,
492              (key_len - i) > hash_len ? hash_len : key_len - i);
493     }
494     break;
495
496   case SILC_PGP_S2K_SALTED:
497     /* Hash passphrase with salt */
498     for (i = 0; i < key_len; i += hash_len) {
499       if (i && i < sizeof(preload)) {
500         silc_hash_init(h);
501         silc_hash_update(h, preload, i);
502       }
503
504       silc_hash_update(h, salt, 8);
505       silc_hash_update(h, passphrase, passphrase_len);
506       silc_hash_final(h, digest);
507       memcpy(key + i, digest,
508              (key_len - i) > hash_len ? hash_len : key_len - i);
509     }
510     break;
511
512   case SILC_PGP_S2K_ITERATED_SALTED:
513     /* Hash passphrase with salt iteratively.  This is very poorly defined
514        in the RFC. */
515     if (iter_octet_count < 8 + passphrase_len)
516       iter_octet_count = 8 + passphrase_len;
517
518     for (i = 0; i < key_len; i += hash_len) {
519       if (i && i < sizeof(preload)) {
520         silc_hash_init(h);
521         silc_hash_update(h, preload, i);
522       }
523
524       for (k = 0; k < iter_octet_count; k += (8 + passphrase_len)) {
525         if (iter_octet_count - k < 8) {
526           silc_hash_update(h, salt, iter_octet_count - k);
527         } else {
528           silc_hash_update(h, salt, 8);
529           if (iter_octet_count - k - 8 < passphrase_len)
530             silc_hash_update(h, passphrase, iter_octet_count - k - 8);
531           else
532             silc_hash_update(h, passphrase, passphrase_len);
533         }
534       }
535
536       silc_hash_final(h, digest);
537       memcpy(key + i, digest,
538              (key_len - i) > hash_len ? hash_len : key_len - i);
539     }
540     break;
541
542   default:
543     goto err;
544     break;
545   }
546
547   memset(digest, 0, sizeof(digest));
548   memset(esalt, 0, sizeof(esalt));
549   silc_hash_free(h);
550
551   return key;
552
553  err:
554   silc_hash_free(h);
555   silc_free(key);
556   return NULL;
557 }
558
559 /****************************** ASCII armoring ******************************/
560
561 /* Adds ASCII armor */
562
563 unsigned char *silc_pgp_armor(unsigned char *data,
564                               SilcUInt32 data_len)
565 {
566   /* XXX TODO */
567   return NULL;
568 }
569
570 /* Removes ASCII armoring */
571
572 unsigned char *silc_pgp_dearmor(unsigned char *data,
573                                 SilcUInt32 data_len,
574                                 SilcUInt32 *ret_len)
575 {
576   int i, k;
577
578   if (data_len < 28)
579     return NULL;
580
581   if (memcmp(data, "-----BEGIN PGP ", 15))
582     return NULL;
583
584   /* Get beginning of base64 encoded data */
585   for (i = 0; i < data_len; i++) {
586     if (i + 3 < data_len && data[i] == '\n' && data[i + 1] == '\n') {
587       i += 2;
588       break;
589     }
590     if (i + 3 < data_len &&
591         data[i] == '\n' && data[i + 1] == ' ' && data[i + 2] == '\n') {
592       i += 3;
593       break;
594     }
595   }
596
597   /* Get end of base64 encoded data, ignore OpenPGP radix64 CRC */
598   for (k = i; k < data_len; k++) {
599     if (k + 1 < data_len && data[k] == '=') {
600       data_len -= (data_len - ++k);
601       break;
602     }
603   }
604
605   return silc_base64_decode(NULL, data + i, data_len, ret_len);
606 }