home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xntp3.zip / authstuff / keyparity.c < prev    next >
C/C++ Source or Header  |  1989-07-25  |  5KB  |  271 lines

  1. /*
  2.  * keyparity - add parity bits to key and/or change an ascii key to binary
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <strings.h>
  8. #include <ctype.h>
  9.  
  10. #define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  11.  
  12. /*
  13.  * Types of ascii representations for keys.  "Standard" means a 64 bit
  14.  * hex number in NBS format, i.e. with the low order bit of each byte
  15.  * a parity bit.  "NTP" means a 64 bit key in NTP format, with the
  16.  * high order bit of each byte a parity bit.  "Ascii" means a 1-to-8
  17.  * character string whose ascii representation is used as the key.
  18.  */
  19. #define    KEY_TYPE_STD    1
  20. #define    KEY_TYPE_NTP    2
  21. #define    KEY_TYPE_ASCII    3
  22.  
  23. #define    STD_PARITY_BITS    0x01010101
  24.  
  25. char *progname;
  26. int debug;
  27.  
  28. int ntpflag = 0;
  29. int stdflag = 0;
  30. int asciiflag = 0;
  31. int ntpoutflag = 0;
  32. int gotoopt = 0;
  33.  
  34. /*
  35.  * main - parse arguments and handle options
  36.  */
  37. main(argc, argv)
  38. int argc;
  39. char *argv[];
  40. {
  41.     int c;
  42.     int errflg = 0;
  43.     int keytype;
  44.     u_long key[2];
  45.     extern int optind;
  46.     extern char *optarg;
  47.  
  48.     progname = argv[0];
  49.     while ((c = getopt(argc, argv, "adno:s")) != EOF)
  50.         switch (c) {
  51.         case 'a':
  52.             asciiflag = 1;
  53.             break;
  54.         case 'd':
  55.             ++debug;
  56.             break;
  57.         case 'n':
  58.             ntpflag = 1;
  59.             break;
  60.         case 's':
  61.             stdflag = 1;
  62.             break;
  63.         case 'o':
  64.             if (*optarg == 'n') {
  65.                 ntpoutflag = 1;
  66.                 gotoopt = 1;
  67.             } else if (*optarg == 's') {
  68.                 ntpoutflag = 0;
  69.                 gotoopt = 1;
  70.             } else {
  71.                 (void) fprintf(stderr,
  72.                     "%s: output format must be `n' or `s'\n",
  73.                     progname);
  74.                 errflg++;
  75.             }
  76.             break;
  77.         default:
  78.             errflg++;
  79.             break;
  80.         }
  81.     if (errflg || optind == argc) {
  82.         (void) fprintf(stderr,
  83.             "usage: %s -n|-s [-a] [-o n|s] key [...]\n",
  84.             progname);
  85.         exit(2);
  86.     }
  87.  
  88.     if (!ntpflag && !stdflag) {
  89.         (void) fprintf(stderr,
  90.             "%s: one of either the -n or -s flags must be specified\n",
  91.             progname);
  92.         exit(2);
  93.     }
  94.  
  95.     if (ntpflag && stdflag) {
  96.         (void) fprintf(stderr,
  97.             "%s: only one of the -n and -s flags may be specified\n",
  98.             progname);
  99.         exit(2);
  100.     }
  101.  
  102.     if (!gotoopt) {
  103.         if (ntpflag)
  104.             ntpoutflag = 1;
  105.     }
  106.  
  107.     if (asciiflag)
  108.         keytype = KEY_TYPE_ASCII;
  109.     else if (ntpflag)
  110.         keytype = KEY_TYPE_NTP;
  111.     else
  112.         keytype = KEY_TYPE_STD;
  113.  
  114.     for (; optind < argc; optind++) {
  115.         if (!decodekey(keytype, argv[optind], key)) {
  116.             (void) fprintf(stderr,
  117.                 "%s: format of key %s invalid\n",
  118.                 progname, argv[optind]);
  119.             exit(1);
  120.         }
  121.         (void) parity(key);
  122.         output(key, ntpoutflag);
  123.     }
  124.     exit(0);
  125. }
  126.  
  127.  
  128.  
  129. /*
  130.  * parity - set parity on a key/check for odd parity
  131.  */
  132. int
  133. parity(key)
  134.     u_long *key;
  135. {
  136.     u_long mask;
  137.     int parity_err;
  138.     int bitcount;
  139.     int half;
  140.     int byte;
  141.     int i;
  142.  
  143.     /*
  144.      * Go through counting bits in each byte.  Check to see if
  145.      * each parity bit was set correctly.  If not, note the error
  146.      * and set it right.
  147.      */
  148.     parity_err = 0;
  149.     for (half = 0; half < 2; half++) {        /* two halves of key */
  150.         mask = 0x80000000;
  151.         for (byte = 0; byte < 4; byte++) {    /* 4 bytes per half */
  152.             bitcount = 0;
  153.             for (i = 0; i < 7; i++) {    /* 7 data bits / byte */
  154.                 if (key[half] & mask)
  155.                     bitcount++;
  156.                 mask >>= 1;
  157.             }
  158.  
  159.             /*
  160.              * If bitcount is even, parity must be set.  If
  161.              * bitcount is odd, parity must be clear.
  162.              */
  163.             if ((bitcount & 0x1) == 0) {
  164.                 if (!(key[half] & mask)) {
  165.                     parity_err++;
  166.                     key[half] |= mask;
  167.                 }
  168.             } else {
  169.                 if (key[half] & mask) {
  170.                     parity_err++;
  171.                     key[half] &= ~mask;
  172.                 }
  173.             }
  174.             mask >>= 1;
  175.         }
  176.     }
  177.  
  178.     /*
  179.      * Return the result of the parity check.
  180.      */
  181.     return (parity_err == 0);
  182. }
  183.  
  184.  
  185. decodekey(keytype, str, key)
  186.     int keytype;
  187.     char *str;
  188.     u_long *key;
  189. {
  190.     u_char keybytes[8];
  191.     char *cp;
  192.     char *xdigit;
  193.     int len;
  194.     int i;
  195.     static char *hex = "0123456789abcdef";
  196.  
  197.     cp = str;
  198.     len = strlen(cp);
  199.     if (len == 0)
  200.         return 0;
  201.  
  202.     switch(keytype) {
  203.     case KEY_TYPE_STD:
  204.     case KEY_TYPE_NTP:
  205.         if (len != 16)        /* Lazy.  Should define constant */
  206.             return 0;
  207.         /*
  208.          * Decode hex key.
  209.          */
  210.         key[0] = 0;
  211.         key[1] = 0;
  212.         for (i = 0; i < 16; i++) {
  213.             if (!isascii(*cp))
  214.                 return 0;
  215.             xdigit = index(hex, isupper(*cp) ? tolower(*cp) : *cp);
  216.             cp++;
  217.             if (xdigit == 0)
  218.                 return 0;
  219.             key[i>>3] <<= 4;
  220.             key[i>>3] |= (u_long)(xdigit - hex) & 0xf;
  221.         }
  222.  
  223.         /*
  224.          * If this is an NTP format key, put it into NBS format
  225.          */
  226.         if (keytype == KEY_TYPE_NTP) {
  227.             for (i = 0; i < 2; i++)
  228.                 key[i] = ((key[i] << 1) & ~STD_PARITY_BITS)
  229.                     | ((key[i] >> 7) & STD_PARITY_BITS);
  230.         }
  231.         break;
  232.     
  233.     case KEY_TYPE_ASCII:
  234.         /*
  235.          * Make up key from ascii representation
  236.          */
  237.         bzero(keybytes, sizeof(keybytes));
  238.         for (i = 0; i < 8 && i < len; i++)
  239.             keybytes[i] = *cp++ << 1;
  240.         key[0] = keybytes[0] << 24 | keybytes[1] << 16
  241.             | keybytes[2] << 8 | keybytes[3];
  242.         key[1] = keybytes[4] << 24 | keybytes[5] << 16
  243.             | keybytes[6] << 8 | keybytes[7];
  244.         break;
  245.     
  246.     default:
  247.         /* Oh, well */
  248.         return 0;
  249.     }
  250.  
  251.     return 1;
  252. }
  253.  
  254.  
  255. /*
  256.  * output - print a hex key on the standard output
  257.  */
  258. output(key, ntpformat)
  259.     u_long *key;
  260.     int ntpformat;
  261. {
  262.     int i;
  263.  
  264.     if (ntpformat) {
  265.         for (i = 0; i < 2; i++)
  266.             key[i] = ((key[i] & ~STD_PARITY_BITS) >> 1)
  267.                 | ((key[i] & STD_PARITY_BITS) << 7);
  268.     }
  269.     (void) printf("%08x%08x\n", key[0], key[1]);
  270. }
  271.