mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

mpgp.c (6229B)


      1 /* mpgp -- (C) 2000 - 2006 Ulf Moeller and others.
      2 
      3    mpgp may be redistributed and modified under certain conditions.
      4    This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
      5    ANY KIND, either express or implied. See the file COPYRIGHT for
      6    details.
      7 
      8    Test application for OpenPGP features
      9    $Id: mpgp.c 934 2006-06-24 13:40:39Z rabbi $ */
     10 
     11 #define MPGPVERSION "0.3.0"
     12 
     13 #include "mix3.h"
     14 #include "pgp.h"
     15 #include <stdlib.h>
     16 #include <string.h>
     17 #include <fcntl.h>
     18 #include <assert.h>
     19 #include <sys/types.h>
     20 #include <sys/stat.h>
     21 #include <time.h>
     22 #include <fcntl.h>
     23 #ifdef POSIX
     24 #include <unistd.h>
     25 #include <termios.h>
     26 #endif /* POSIX */
     27 
     28 int pass(BUFFER *b)
     29 {
     30   char p[LINELEN];
     31   int fd;
     32   int n;
     33 
     34 #ifdef HAVE_TERMIOS
     35   struct termios attr;
     36 #endif /* HAVE_TERMIOS */
     37 
     38   fprintf(stderr, "enter passphrase: ");
     39   fflush(stderr);
     40 #ifdef HAVE_TERMIOS
     41   fd = open("/dev/tty", O_RDONLY);
     42   if (tcgetattr(fd, &attr) != 0)
     43     return (-1);
     44   attr.c_lflag &= ~ECHO;
     45   attr.c_lflag |= ICANON;
     46   if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
     47     return (-1);
     48   n = read(fd, p, LINELEN);
     49 
     50   attr.c_lflag |= ECHO;
     51   if (tcsetattr(fd, TCSAFLUSH, &attr) != 0)
     52     return (-1);
     53   close(fd);
     54   p[n - 1] = 0;
     55 
     56 #else /* end of HAVE_TERMIOS */
     57   fgets(p, LINELEN, stdin);
     58   if (p[strlen(p)-1]=='\n')
     59     p[strlen(p)-1] = 0;
     60 #endif /* else if not HAVE_TERMIOS */
     61 
     62   fprintf(stderr, "\n");
     63   buf_appends(b, p);
     64   return (0);
     65 }
     66 
     67 void usage(char *n)
     68 {
     69   fprintf(stderr, "Usage: %s -e [-b] user@domain\n", n);
     70   fprintf(stderr, "       %s -s [-b] [yourname@domain]\n", n);
     71   fprintf(stderr, "       %s -c [-b]\n", n);
     72   fprintf(stderr, "       %s -C [-b]\n", n);
     73   fprintf(stderr, "       %s -d [passphrase]\n", n);
     74   fprintf(stderr, "       %s -g[r] yourname@domain [bits]\n", n);
     75   fprintf(stderr, "       %s -a[+-] [-b]\n", n);
     76   fprintf(stderr, "       %s -V\n\n", n);
     77   fprintf(stderr, "PGP public key ring: %s\n", PGPPUBRING);
     78   fprintf(stderr, "PGP secret key ring: %s\n", PGPSECRING);
     79 }
     80 
     81 int decrypt(BUFFER *u, BUFFER *option, char *n)
     82 {
     83   BUFFER *v;
     84   BUFFER *sig;
     85   int err = 0;
     86 
     87   v = buf_new();
     88   sig = buf_new();
     89 
     90   buf_set(v, u);
     91   err = pgp_decrypt(v, NULL, sig, PGPPUBRING, PGPSECRING);
     92   if (err >= 0 || err == PGP_SIGBAD)
     93     buf_move(u, v);
     94 
     95   if (err == PGP_ERR) {
     96     pass(option);
     97     err = pgp_decrypt(u, option, sig, PGPPUBRING, PGPSECRING);
     98   }
     99   switch (err) {
    100   case PGP_NOMSG:
    101     fprintf(stderr, "%s: Not a PGP message.\n", n);
    102     break;
    103   case PGP_ERR:
    104     fprintf(stderr, "%s: Can't read message.\n", n);
    105     break;
    106   case PGP_SIGOK:
    107     fprintf(stderr, "%s: Valid signature: %s\n", n, sig->data);
    108     err = 0;
    109     break;
    110   case PGP_SIGNKEY:
    111     fprintf(stderr, "%s: Unknown signature key %s, cannot verify.\n", n, sig->data);
    112     err = 1;
    113     break;
    114   case PGP_SIGBAD:
    115     fprintf(stderr, "%s: Bad signature.\n", n);
    116     err = 1;
    117     break;
    118   }
    119 
    120   buf_free(v);
    121   buf_free(sig);
    122 
    123   return (err);
    124 }
    125 
    126 int main(int argc, char *argv[])
    127 {
    128   BUFFER *u, *option, *pp;
    129   char *filename = NULL;
    130   char *cmd = NULL;
    131   int text = 1;
    132   int err = 99;
    133   int bits = 0;
    134 
    135   mix_init(NULL);
    136   VERBOSE = 3;
    137 
    138   u = buf_new();
    139   option = buf_new();
    140   pp = buf_new();
    141 
    142   if (argc > 1 && argv[1][0] == '-')
    143     cmd = argv[1];
    144 
    145   if (argc == 1 || (cmd > 0 && (cmd[1] == 'e' || cmd[1] == 'c' ||
    146 				cmd[1] == 'd' || cmd[1] == 'a' ||
    147 				cmd[1] == 's' || cmd[1] == 'C'))) {
    148     if ((argc > 2 && (cmd == NULL || cmd[1] == 'a')) || argc > 3) {
    149       FILE *f;
    150 
    151       f = fopen(argv[argc - 1], "rb");
    152       if (f == NULL) {
    153 	fprintf(stderr, "%s: Can't open %s\n", argv[0], argv[argc - 1]);
    154 	err = -1;
    155       } else {
    156 	buf_read(u, f);
    157 	fclose(f);
    158 	filename = argv[argc - 1];
    159 	argc--;
    160       }
    161     } else
    162       buf_read(u, stdin);
    163   }
    164   if (argc == 1)
    165     err = decrypt(u, option, argv[0]);
    166 
    167   if (argc > 2 && argv[2][0] == '-' && argv[2][1] == 'b') {
    168     text = 0;
    169     if (argc > 3)
    170       buf_appends(option, argv[3]);
    171   } else if (argc > 2)
    172     buf_appends(option, argv[2]);
    173 
    174   if (cmd)
    175     switch (cmd[1]) {
    176     case 's':
    177       err = pgp_encrypt(PGP_SIGN | (text ? PGP_TEXT : 0), u, NULL, option,
    178 			NULL, PGPPUBRING, PGPSECRING);
    179       if (err != 0) {
    180 	pass(pp);
    181 	err = pgp_encrypt(PGP_SIGN | (text ? PGP_TEXT : 0), u, NULL, option,
    182 			  pp, PGPPUBRING, PGPSECRING);
    183       }
    184       if (err != 0)
    185 	fprintf(stderr, "Error.\n");
    186       break;
    187     case 'e':
    188       if (option->length) {
    189 	err = pgp_encrypt(PGP_ENCRYPT | (text ? PGP_TEXT : 0), u, option, NULL,
    190 			  NULL, PGPPUBRING, PGPSECRING);
    191 	if (err < 0)
    192 	  fprintf(stderr, "%s: can't encrypt message for %s\n",
    193 		  argv[0], argv[2]);
    194       }
    195       break;
    196     case 'c':
    197       pass(option);
    198       err = pgp_encrypt(PGP_CONVENTIONAL | (text ? PGP_TEXT : 0), u, option,
    199 			NULL, NULL, PGPPUBRING, PGPSECRING);
    200       if (err < 0)
    201 	fprintf(stderr, "%s: can't encrypt message\n", argv[0]);
    202       break;
    203     case 'C':
    204       pass(option);
    205       err = pgp_encrypt(PGP_NCONVENTIONAL | (text ? PGP_TEXT : 0), u, option,
    206 			NULL, NULL, PGPPUBRING, PGPSECRING);
    207       if (err < 0)
    208 	fprintf(stderr, "%s: can't encrypt message\n", argv[0]);
    209       break;
    210     case 'g':
    211       if (argc < 3) {
    212 	err = 99;
    213 	goto end;
    214       }
    215       pass(pp);
    216       if (argc == 4)
    217 	sscanf(argv[3], "%d", &bits);
    218       err = pgp_keygen(cmd[2] == 'r' ? PGP_ES_RSA : PGP_E_ELG,
    219 		       bits, option, pp, PGPPUBRING, PGPSECRING, 0);
    220       break;
    221     case 'a':
    222       switch (cmd[2]) {
    223       case '-':
    224 	err = pgp_dearmor(u, u);
    225 	if (err == -1)
    226 	  fprintf(stderr, "Not a PGP-armored message\n");
    227 	goto end;
    228       case '+':
    229 	break;
    230       default:
    231 	pgp_literal(u, filename, text);
    232 	pgp_compress(u);
    233 	break;
    234       }
    235       err = pgp_armor(u, PGP_ARMOR_NORMAL);
    236       break;
    237     case 'd':
    238       err = decrypt(u, option, argv[0]);
    239       break;
    240     case 'h':
    241       usage(argv[0]);
    242       err = 0;
    243       break;
    244     case 'V':
    245       fprintf(stderr, "mpgp version %s\n", MPGPVERSION);
    246       fprintf(stderr, "(C) 2000 - 2004 Ulf Moeller and others.\n");
    247       fprintf(stderr, "See the file COPYRIGHT for details.\n");
    248       err = 0;
    249       break;
    250     }
    251 end:
    252   if (err == 99)
    253     usage(argv[0]);
    254 
    255   if (err >= 0)
    256     buf_write(u, stdout);
    257 
    258   buf_free(option);
    259   buf_free(pp);
    260   buf_free(u);
    261 
    262   mix_exit();
    263   return (err == -1 ? 1 : err);
    264 }