Changeset 9a4077c for zcrypt.c


Ignore:
Timestamp:
Mar 17, 2010, 10:36:59 PM (15 years ago)
Author:
Nelson Elhage <nelhage@ksplice.com>
Branches:
master, release-1.10, release-1.6, release-1.7, release-1.8, release-1.9
Children:
c836519
Parents:
f7f35c0
git-author:
Nelson Elhage <nelhage@mit.edu> (04/13/09 23:48:04)
git-committer:
Nelson Elhage <nelhage@ksplice.com> (03/17/10 22:36:59)
Message:
zcrypt.c: Refactor encryption.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • zcrypt.c

    rf7f35c0 r9a4077c  
    2424
    2525#define MAX_KEY 128
     26#define MAX_LINE 128
    2627
    2728#ifndef TRUE
     
    4849
    4950char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance);
     51int ParseCryptSpec(char *spec, char **keyfile);
    5052char *BuildArgString(char **argv, int start, int end);
    51 int do_encrypt(char *keystring, int zephyr, char *class, char *instance,
    52           ZWRITEOPTIONS *zoptions, char* keyfile);
     53char *read_keystring(char *keyfile);
     54int do_encrypt(int zephyr, char *class, char *instance,
     55               ZWRITEOPTIONS *zoptions, char* keyfile, int cipher);
     56int do_encrypt_des(char *keyfile, char *in, int len, FILE *out);
    5357int do_decrypt(char *keystring);
    5458
     
    6064#define M_SETKEY          5
    6165
     66#define CIPHER_ERR        -1
     67#define CIPHER_DES        0
     68#define CIPHER_AES        1
     69
    6270static void owl_zcrypt_string_to_schedule(char *keystring, des_key_schedule schedule) {
    6371#ifdef HAVE_KERBEROS_IV
     
    7381int main(int argc, char *argv[])
    7482{
    75   char *fname = NULL;
     83  char *cryptspec = NULL;
     84  char *keyfile;
     85  int cipher;
    7686  int error = FALSE;
    7787  int zephyr = FALSE;
     
    113123      case 'F':
    114124        /* Specify the keyfile explicitly */
    115         if (fname != NULL) error = TRUE;
    116         fname = optarg;
     125        if (cryptspec != NULL) error = TRUE;
     126        cryptspec = optarg;
    117127        break;
    118128      case 'c':
     
    205215    error = TRUE;
    206216
    207   if (!error && fname == NULL && (class != NULL || instance != NULL))
    208     fname = GetZephyrVarKeyFile(argv[0], class, instance);
    209  
     217  if (!error && cryptspec == NULL && (class != NULL || instance != NULL)) {
     218    cryptspec = GetZephyrVarKeyFile(argv[0], class, instance);
     219    if(!cryptspec) {
     220      fprintf(stderr, "Unable to find keyfile for ");
     221      if(class != NULL) {
     222        fprintf(stderr, "-c %s ", class);
     223      }
     224      if(instance != NULL) {
     225        fprintf(stderr, "-i %s ", instance);
     226      }
     227      fprintf(stderr, "\n");
     228      exit(-1);
     229    }
     230  }
     231
    210232  if (error)
    211233  {
     
    215237    exit(1);
    216238  }
    217   else if(!fname)
    218   {
     239
     240  cipher = ParseCryptSpec(cryptspec, &keyfile);
     241  if(cipher < 0) {
     242    fprintf(stderr, "Invalid cipher specification: %s\n", cryptspec);
    219243    exit(1);
    220244  }
    221   else
    222   {
    223     if (mode == M_RANDOMIZE)
    224     {
    225       /* Choose a new, random key */
    226 /*
     245
     246
     247  if (mode == M_RANDOMIZE)
     248  {
     249    /* Choose a new, random key */
     250    /*
    227251      FILE *fkey = fopen(fname, "w");
    228252      if (!fkey)
    229         printf("Could not open key file for writing: %s\n", fname);
     253      printf("Could not open key file for writing: %s\n", fname);
    230254      else
    231255      {
    232         char string[100];
    233         fputs(fkey, string);
     256      char string[100];
     257      fputs(fkey, string);
     258      fclose(fkey);
     259      }
     260    */
     261    fprintf(stderr, "Feature not yet implemented.\n");
     262  }
     263  else if (mode == M_SETKEY)
     264  {
     265    /* Set a new, user-entered key */
     266    char newkey[MAX_KEY];
     267    FILE *fkey;
     268
     269    if (isatty(0))
     270    {
     271      printf("Enter new key: ");
     272      /* Really should read without echo!!! */
     273    }
     274    if(!fgets(newkey, MAX_KEY - 1, stdin)) {
     275      fprintf(stderr, "Error reading key.\n");
     276      return 1;
     277    }
     278
     279    fkey = fopen(keyfile, "w");
     280    if (!fkey)
     281      fprintf(stderr, "Could not open key file for writing: %s\n", keyfile);
     282    else
     283    {
     284      if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n')
     285      {
     286        fprintf(stderr, "Error writing to key file.\n");
    234287        fclose(fkey);
    235         }
    236  */
    237       fprintf(stderr, "Feature not yet implemented.\n");
    238     }
    239     else if (mode == M_SETKEY)
    240     {
    241       /* Set a new, user-entered key */
    242       char newkey[MAX_KEY];
    243       FILE *fkey;
    244 
    245       if (isatty(0))
    246       {
    247         printf("Enter new key: ");
    248         /* Really should read without echo!!! */
    249       }
    250       if(!fgets(newkey, MAX_KEY - 1, stdin)) {
    251         fprintf(stderr, "Error reading key.\n");
    252         return 1;
    253       }
    254 
    255       fkey = fopen(fname, "w");
    256       if (!fkey)
    257         fprintf(stderr, "Could not open key file for writing: %s\n", fname);
    258       else
    259       {
    260         if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n')
    261         {
    262           fprintf(stderr, "Error writing to key file.\n");
    263           fclose(fkey);
    264           exit(1);
    265         }
    266         else
    267         {
    268           fclose(fkey);
    269           fprintf(stderr, "Key update complete.\n");
    270         }
    271       }
    272     }
    273     else
    274     {
    275       /* Encrypt/decrypt */
    276       FILE *fkey = fopen(fname, "r");
    277       if (!fkey) {
    278         fprintf(stderr, "Could not open key file: %s\n", fname);
    279288        exit(1);
    280289      }
    281290      else
    282291      {
    283         char keystring[MAX_KEY];
    284         if(!fgets(keystring, MAX_KEY-1, fkey)) {
    285           fclose(fkey);
    286           fprintf(stderr, "Error reading key file.\n");
    287           return 1;
    288         }
    289         if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT)
    290           do_encrypt(keystring, (mode == M_ZEPHYR_ENCRYPT), class, instance,
    291                      &zoptions, fname);
    292         else
    293           do_decrypt(keystring);
    294292        fclose(fkey);
     293        fprintf(stderr, "Key update complete.\n");
    295294      }
    296295    }
     296  }
     297  else
     298  {
     299    if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT)
     300      do_encrypt((mode == M_ZEPHYR_ENCRYPT), class, instance,
     301                 &zoptions, keyfile, cipher);
     302    else
     303      do_decrypt(keyfile);
    297304  }
    298305
     
    301308    printf("**END**\n");
    302309  return 0;
     310}
     311
     312int ParseCryptSpec(char *spec, char **keyfile) {
     313  *keyfile = spec;
     314  return CIPHER_DES;
    303315}
    304316
     
    400412      }
    401413
    402     if (keyfile == NULL)
    403     {
    404       fprintf(stderr, "Could not find key table entry.\n");
    405     }
    406     else
     414    if (keyfile != NULL)
    407415    {
    408416      /* Prepare result to be returned */
     
    414422        fprintf(stderr, "Memory allocation error.\n");
    415423    }
    416    
    417424    fclose(fsearch);
    418425  }
     
    531538}
    532539
    533 #define MAX_LINE 128
    534 
    535 /* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite
    536    if zephyr is set. */
    537 int do_encrypt(char *keystring, int zephyr, char *class, char *instance,
    538           ZWRITEOPTIONS *zoptions, char* keyfile)
    539 {
    540   des_key_schedule schedule;
    541   unsigned char input[8], output[8];
    542   int size;
    543   FILE *outfile = stdout;
    544   int error = FALSE;
    545   char *inbuff = NULL, *inptr;
    546   int freein = FALSE;
    547   int use_buffer = FALSE;
    548   int num_blocks = 0, last_block_size = 0;
    549 
    550   owl_zcrypt_string_to_schedule(keystring, schedule);
    551 
    552   if (zephyr)
    553   {
    554     if (zoptions->flags & ZCRYPT_OPT_MESSAGE)
    555     {
    556       /* Use the -m message */
    557       int length;
    558       inbuff = zoptions->message;     
    559       length = strlen(inbuff);
    560       num_blocks = (length + 7) / 8;
    561       last_block_size = ((length + 7) % 8) + 1;
    562       use_buffer = TRUE;
    563     }
    564     else if (isatty(0))
    565     {
     540char *GetInputBuffer(ZWRITEOPTIONS *zoptions, int *length) {
     541  char *buf;
     542  char *inptr;
     543
     544  if (zoptions->flags & ZCRYPT_OPT_MESSAGE)
     545  {
     546    /* Use the -m message */
     547    buf = strdup(zoptions->message);
     548    *length = strlen(buf);
     549  }
     550  else
     551  {
     552    if (isatty(0)) {
    566553      /* tty input, so show the "Type your message now..." message */
    567554      if (zoptions->flags & ZCRYPT_OPT_IGNOREDOT)
     
    569556      else
    570557        printf("Type your message now.  End with control-D or a dot on a line by itself.\n");
    571       use_buffer = TRUE;
    572       if ((inptr = inbuff = (char *)malloc(MAX_RESULT)) == NULL)
     558    } else {
     559      zoptions->flags |= ZCRYPT_OPT_IGNOREDOT;
     560    }
     561
     562    if ((inptr = buf = (char *)malloc(MAX_RESULT)) == NULL)
     563    {
     564      fprintf(stderr, "Memory allocation error\n");
     565      return NULL;
     566    }
     567    while (inptr - buf < MAX_RESULT - MAX_LINE - 20)
     568    {
     569      if (!fgets(inptr, MAX_LINE, stdin)) break;
     570      if (inptr[0])
    573571      {
    574         fprintf(stderr, "Memory allocation error\n");
    575         return FALSE;
    576       }
    577       while (inptr - inbuff < MAX_RESULT - MAX_LINE - 20)
    578       {
    579         if (!fgets(inptr, MAX_LINE, stdin))
    580           return FALSE;
    581         if (inptr[0])
     572        if (inptr[0] == '.' && inptr[1] == '\n' &&
     573            !(zoptions->flags & ZCRYPT_OPT_IGNOREDOT))
    582574        {
    583           if (inptr[0] == '.' && inptr[1] == '\n' &&
    584               !(zoptions->flags & ZCRYPT_OPT_IGNOREDOT))
    585           {
    586             inptr[0] = '\0';
    587             break;
    588           }
    589           else
    590             inptr += strlen(inptr);
     575          inptr[0] = '\0';
     576          break;
    591577        }
    592578        else
    593           break;
     579          inptr += strlen(inptr);
    594580      }
    595       num_blocks = (inptr - inbuff + 7) / 8;
    596       last_block_size = ((inptr - inbuff + 7) % 8) + 1;
    597       freein = TRUE;
    598     }
    599 
    600     /* if (zephyr) */
     581      else
     582        break;
     583    }
     584    *length = inptr - buf;
     585  }
     586  return buf;
     587}
     588
     589char *read_keystring(char *keyfile) {
     590  char *keystring;
     591  FILE *fkey = fopen(keyfile, "r");
     592  if(!fkey) {
     593    fprintf(stderr, "Unable to open keyfile %s\n", keyfile);
     594    return NULL;
     595  }
     596  keystring = malloc(MAX_KEY);
     597  if(!fgets(keystring, MAX_KEY-1, fkey)) {
     598    fprintf(stderr, "Unable to read from keyfile: %s\n", keyfile);
     599    free(keystring);
     600    keystring = NULL;
     601  }
     602  fclose(fkey);
     603  return keystring;
     604}
     605
     606/* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite
     607   if zephyr is set. */
     608int do_encrypt(int zephyr, char *class, char *instance,
     609               ZWRITEOPTIONS *zoptions, char* keyfile, int cipher)
     610{
     611  FILE *outfile = stdout;
     612  char *inbuff = NULL;
     613  int buflen;
     614  int out = TRUE;
     615
     616  inbuff = GetInputBuffer(zoptions, &buflen);
     617
     618  if(!inbuff) {
     619    fprintf(stderr, "Error reading zcrypt input!\n");
     620    return FALSE;
     621  }
     622
     623  if (zephyr) {
    601624    outfile = GetZephyrPipe(class, instance, zoptions);
    602625    if (!outfile)
    603626    {
    604627      fprintf(stderr, "Could not run zwrite\n");
    605       if (freein && inbuff)
     628      if (inbuff)
    606629        free(inbuff);
    607630      return FALSE;
     
    609632  }
    610633
    611   inptr = inbuff;
     634  switch(cipher) {
     635  case CIPHER_DES:
     636    out = do_encrypt_des(keyfile, inbuff, buflen, outfile);
     637    break;
     638  case CIPHER_AES:
     639    out = FALSE;
     640    break;
     641  }
     642
     643  if (zephyr)
     644    CloseZephyrPipe(outfile);
     645
     646  free(inbuff);
     647  return out;
     648}
     649
     650int do_encrypt_des(char *keyfile, char *in, int length, FILE *outfile)
     651{
     652  des_key_schedule schedule;
     653  unsigned char input[8], output[8];
     654  char *inptr;
     655  int num_blocks, last_block_size;
     656  char *keystring;
     657  int size;
     658
     659  keystring = read_keystring(keyfile);
     660  if(!keystring) {
     661    return FALSE;
     662  }
     663
     664  owl_zcrypt_string_to_schedule(keystring, schedule);
     665  free(keystring);
     666
     667  inptr = in;
     668  num_blocks = (length + 7) / 8;
     669  last_block_size = ((length + 7) % 8) + 1;
    612670
    613671  /* Encrypt the input (inbuff or stdin) and send it to outfile */
    614672  while (TRUE)
    615673  {
    616     if (use_buffer)
    617     {
    618       /* Get 8 bytes from buffer */
    619       if (num_blocks > 1)
    620       {
    621         size = 8;
    622         memcpy(input, inptr, size);
    623         inptr += 8;
    624         num_blocks--;
    625       }
    626       else if (num_blocks == 1)
    627       {
    628         size = last_block_size;
    629         memcpy(input, inptr, size);
    630         num_blocks--;
    631       }
    632       else
    633         size = 0;
     674    /* Get 8 bytes from buffer */
     675    if (num_blocks > 1)
     676    {
     677      size = 8;
     678      memcpy(input, inptr, size);
     679      inptr += 8;
     680      num_blocks--;
     681    }
     682    else if (num_blocks == 1)
     683    {
     684      size = last_block_size;
     685      memcpy(input, inptr, size);
     686      num_blocks--;
    634687    }
    635688    else
    636       /* Get 8 bytes from stdin */
    637       size = fread(input, 1, 8, stdin);
     689      size = 0;
    638690
    639691    /* Check for EOF and pad the string to 8 chars, if needed */
    640692    if (size == 0)
    641       break;                      /* END OF INPUT: BREAK FROM while LOOP! */
     693      break;
    642694    if (size < 8)
    643695      memset(input + size, 0, 8 - size);
     
    651703  }
    652704
    653   /* Close out the output */
    654   if (!error)
    655     putc('\n', outfile);
    656   if (zephyr)
    657     CloseZephyrPipe(outfile);
    658 
    659   /* Free the input buffer, if necessary */
    660   if (freein && inbuff)
    661     free(inbuff);
    662 
    663   return !error;
     705  putc('\n', outfile);
     706
     707  return TRUE;
    664708}
    665709
     
    715759
    716760/* Decrypt stdin */
    717 void do_decrypt(char *keystring)
     761int do_decrypt(char *keystring)
    718762{
    719763  des_key_schedule schedule;
     
    732776  if (!output[0] || output[strlen((const char*)output) - 1] != '\n')
    733777      printf("\n");
    734 }
     778  return TRUE;
     779}
Note: See TracChangeset for help on using the changeset viewer.