Subversion Repositories oidconverter

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*###################################################################
  2. ###                                                               ###
  3. ### Object ID converter. Matthias Gaertner, 06/1999               ###
  4. ### Converted to plain 'C' 07/2001                                ###
  5. ###                                                               ###
  6. ### To compile with gcc simply use:                               ###
  7. ###   gcc -O2 -o oid oid.c                                        ###
  8. ###                                                               ###
  9. ### To compile using cl, use:                                     ###
  10. ###   cl -DWIN32 -O1 oid.c                                        ###
  11. ###                                                               ###
  12. ### Freeware - do with it whatever you want.                      ###
  13. ### Use at your own risk. No warranty of any kind.                ###
  14. ###                                                               ###
  15. ###################################################################*/
  16. /* $Version: 1.1$ */
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21.  
  22. #ifndef __STRNICMP_LOCAL
  23. #ifdef WIN32
  24. #define __STRNICMP_LOCAL strnicmp
  25. #else
  26. #define __STRNICMP_LOCAL strncasecmp
  27. #endif
  28. #endif
  29.  
  30. char                    abCommandLine[256];
  31. unsigned char   abBinary[128];
  32. unsigned int    nBinary = 0;
  33.  
  34.  
  35. static void MakeBase128( unsigned long l, int first )
  36. {
  37.         if( l > 127 )
  38.         {
  39.                 MakeBase128( l / 128, 0 );
  40.         }
  41.         l %= 128;
  42.         if( first )
  43.         {
  44.                 abBinary[nBinary++] = (unsigned char)l;
  45.         }
  46.         else
  47.         {
  48.                 abBinary[nBinary++] = 0x80 | (unsigned char)l;
  49.         }
  50. }
  51.  
  52. int main( int argc, char **argv )
  53. {
  54.         char *fOutName = NULL;
  55.         char *fInName = NULL;
  56.         FILE *fOut = NULL;
  57.  
  58.         int n = 1;
  59.         int nMode = 0;  /* dotted->hex */
  60.         int nCHex = 0;
  61.         int nAfterOption = 0;
  62.  
  63.         if( argc == 1 )
  64.         {
  65.                 fprintf( stderr,
  66.                 "OID encoder/decoder - Matthias Gaertner 1999/2001 - Freeware\n"
  67.                 "Usage:\n"
  68.                 " OID [-C] [-o<outfile>] {-i<infile>|1.2.3.4}\n"
  69.                 "   converts dotted form to ASCII HEX DER output.\n"
  70.                 " OID -x [-o<outfile>] {-i<infile>|hex-digits}\n"
  71.                 "   decodes ASCII HEX DER and gives dotted form.\n" );
  72.                 return 1;
  73.         }
  74.  
  75.         while( n < argc )
  76.         {
  77.                 if( !nAfterOption && argv[n][0] == '-' )
  78.                 {
  79.                         if( argv[n][1] == 'x' )
  80.                         {
  81.                                 nMode = 1;      /* hex->dotted */
  82.                                 if( argv[n][2] != '\0' )
  83.                                 {
  84.                                         argv[n--] += 2;
  85.                                         nAfterOption = 1;
  86.                                 }
  87.                         }
  88.                         else if( argv[n][1] == 'C' )
  89.                         {
  90.                                 nMode = 0;
  91.                                 nCHex = 1;
  92.  
  93.                                 if( argv[n][2] != '\0' )
  94.                                 {
  95.                                         argv[n--] += 2;
  96.                                         nAfterOption = 1;
  97.                                 }
  98.                         }
  99.                         else if( argv[n][1] == 'o' )
  100.                         {
  101.                                 if( argv[n][2] != '\0' )
  102.                                 {
  103.                                         fOutName = &argv[n][2];
  104.                                 }
  105.                                 else if( n < argc-1 )
  106.                                 {
  107.                                         fOutName = argv[++n];
  108.                                 }
  109.                                 else
  110.                                 {
  111.                                         fprintf(stderr,"Incomplete command line.\n");
  112.                                 }
  113.                         }
  114.                         else if( argv[n][1] == 'i' )
  115.                         {
  116.                                 if( argv[n][2] != '\0' )
  117.                                 {
  118.                                         fInName = &argv[n][2];
  119.                                 }
  120.                                 else if( n < argc-1 )
  121.                                 {
  122.                                         fInName = argv[++n];
  123.                                 }
  124.                                 else
  125.                                 {
  126.                                         fprintf(stderr,"Incomplete command line.\n");
  127.                                 }
  128.                         }
  129.                 }
  130.                 else
  131.                 {
  132.                         if( fInName != NULL )
  133.                         {
  134.                                 break;
  135.                         }
  136.  
  137.                         nAfterOption = 1;
  138.                         if( strlen( argv[n] ) + strlen( abCommandLine ) >= sizeof(abCommandLine)-2 )
  139.                         {
  140.                                 fprintf(stderr,"Command line too long.\n");
  141.                                 return 2;
  142.                         }
  143.                         strcat( abCommandLine, argv[n] );
  144.                         if( n != argc - 1 && nMode != 1 )
  145.                         {
  146.                                 strcat( abCommandLine, "." );
  147.                         }
  148.                 }
  149.                 n++;
  150.         }
  151.  
  152.         if( fInName != NULL && nMode == 1 )
  153.         {
  154.                 FILE *fIn = fopen( fInName, "rb" );
  155.                 size_t nRead = 0;
  156.                 if( fIn == NULL )
  157.                 {
  158.                         fprintf(stderr,"Unable to open input file %s.\n", fInName );
  159.                         return 11;
  160.                 }
  161.                 nRead = fread( abCommandLine, 1, sizeof(abCommandLine), fIn );
  162.                 abCommandLine[nRead] = '\0';
  163.                 fclose( fIn );
  164.         }
  165.         else if( fInName != NULL && nMode == 0 )
  166.         {
  167.                 FILE *fIn = fopen( fInName, "rt" );
  168.                 if( fIn == NULL )
  169.                 {
  170.                         fprintf(stderr,"Unable to open input file %s.\n", fInName );
  171.                         return 11;
  172.                 }
  173.                 fgets( abCommandLine, sizeof(abCommandLine), fIn );
  174.                 fclose( fIn );
  175.         }
  176.  
  177.         while( nMode == 1 )     /* better if */
  178.         {
  179.                 /* hex->dotted */
  180.                 /*printf("Hex-In: %s\n", abCommandLine );*/
  181.  
  182.                 char *p = abCommandLine;
  183.                 char *q = p;
  184.  
  185.                 unsigned char *pb = NULL;
  186.                 unsigned int nn = 0;
  187.                 unsigned long ll = 0;
  188.                 int fOK = 0;
  189.  
  190.                 while( *p )
  191.                 {
  192.                         if( *p != '.' && *p != '\r' && *p != '\n' && *p != '\x20' && *p != '\t')
  193.                         {
  194.                                 *q++ = *p;
  195.                         }
  196.                         p++;
  197.                 }
  198.                 *q = '\0';
  199.  
  200.                 if( strlen( abCommandLine ) % 2 != 0 )
  201.                 {
  202.                         fprintf(stderr, "OID must have even number of hex digits!\n" );
  203.                         return 2;
  204.                 }
  205.  
  206.                 if( strlen( abCommandLine ) < 3 )
  207.                 {
  208.                         fprintf(stderr, "OID must have at least three bytes!\n" );
  209.                         return 2;
  210.                 }
  211.  
  212.                 nBinary = 0;
  213.                 p = abCommandLine;
  214.  
  215.                 while( *p )
  216.                 {
  217.                         unsigned char b;
  218.                         if( p[0] >= 'A' && p[0] <= 'F' )
  219.                         {
  220.                                 b = (p[0] - 'A' + 10) * 16;
  221.                         }
  222.                         else if( p[0] >= 'a' && p[0] <= 'f' )
  223.                         {
  224.                                 b = (p[0] - 'a' + 10) * 16;
  225.                         }
  226.                         else if( p[0] >= '0' && p[0] <= '9' )
  227.                         {
  228.                                 b = (p[0] - '0') * 16;
  229.                         }
  230.                         else
  231.                         {
  232.                                 fprintf(stderr, "Must have hex digits only!\n" );
  233.                                 return 2;
  234.                         }
  235.                         if( p[1] >= 'A' && p[1] <= 'F' ||
  236.                                 p[1] >= 'a' && p[1] <= 'f' )
  237.                         {
  238.                                 b += (p[1] - 'A' + 10);
  239.                         }
  240.                         else if( p[1] >= '0' && p[1] <= '9' )
  241.                         {
  242.                                 b += (p[1] - '0');
  243.                         }
  244.                         else
  245.                         {
  246.                                 fprintf(stderr, "Must have hex digits only!\n" );
  247.                                 return 2;
  248.                         }
  249.                         abBinary[nBinary++] = b;
  250.                         p += 2;
  251.                 }
  252.  
  253.                 /*printf("Hex-In: %s\n", abCommandLine );*/
  254.  
  255.                 if( fOutName != NULL )
  256.                 {
  257.                         fOut = fopen( fOutName, "wt" );
  258.                         if( fOut == NULL )
  259.                         {
  260.                                 fprintf(stderr,"Unable to open output file %s\n", fOutName );
  261.                                 return 33;
  262.                         }
  263.                 }
  264.                 else
  265.                 {
  266.                         fOut = stdout;
  267.                 }
  268.  
  269.                 pb = abBinary;
  270.                 nn = 0;
  271.                 ll = 0;
  272.                 fOK = 0;
  273.                 while( nn < nBinary )
  274.                 {
  275.                         if( nn == 0 )
  276.                         {
  277.                                 unsigned char cl = ((*pb & 0xC0) >> 6) & 0x03;
  278.                                 switch( cl )
  279.                                 {
  280.                                 default:
  281.                                 case 0: fprintf(fOut,"UNIVERSAL"); break;
  282.                                 case 1: fprintf(fOut,"APPLICATION"); break;
  283.                                 case 2: fprintf(fOut,"CONTEXT"); break;
  284.                                 case 3: fprintf(fOut,"PRIVATE"); break;
  285.                                 }
  286.                                 fprintf(fOut," OID");
  287.                         }
  288.                         else if( nn == 1 )
  289.                         {
  290.                                 if( nBinary - 2 != *pb )
  291.                                 {
  292.                                         if( fOut != stdout )
  293.                                         {
  294.                                                 fclose( fOut );
  295.                                         }
  296.                                         fprintf(stderr,"\nInvalid length (%d)\n", *pb );
  297.                                         return 3;
  298.                                 }
  299.                         }
  300.                         else if( nn == 2 )
  301.                         {
  302.                                 fprintf(fOut,".%d.%d", *pb / 40, *pb % 40 );
  303.                                 fOK = 1;
  304.                                 ll = 0;
  305.                         }
  306.                         else if( (*pb & 0x80) != 0 )
  307.                         {
  308.                                 ll *= 128;
  309.                                 ll += (*pb & 0x7F);
  310.                                 fOK = 0;
  311.                         }
  312.                         else
  313.                         {
  314.                                 ll *= 128;
  315.                                 ll += *pb;
  316.                                 fOK = 1;
  317.  
  318.                                 fprintf(fOut,".%lu", ll );
  319.                                 ll = 0;
  320.                         }
  321.  
  322.                         pb++;
  323.                         nn++;
  324.                 }
  325.  
  326.                 if( !fOK )
  327.                 {
  328.                         fprintf(stderr,"\nEncoding error. The OID is not constructed properly.\n");
  329.                         return 4;
  330.                 }
  331.                 else
  332.                 {
  333.                         fprintf(fOut,"\n");
  334.                 }
  335.  
  336.                 if( fOut != stdout )
  337.                 {
  338.                         fclose( fOut );
  339.                 }
  340.                 break;
  341.         };
  342.  
  343.         while( nMode == 0 )     /* better if */
  344.         {
  345.                 /* dotted->hex */
  346.                 /* printf("OID.%s\n", abCommandLine ); */
  347.  
  348.                 char *p = abCommandLine;
  349.                 unsigned char cl = 0x00;
  350.                 char *q = NULL;
  351.                 int nPieces = 1;
  352.                 int n = 0;
  353.                 unsigned char b = 0;
  354.                 unsigned int nn = 0;
  355.                 unsigned long l = 0;
  356.  
  357.                 if( __STRNICMP_LOCAL( p, "UNIVERSAL.", 10 ) == 0 )
  358.                 {
  359.                         p+=10;
  360.                 }
  361.                 else if( __STRNICMP_LOCAL( p, "APPLICATION.", 12 ) == 0 )
  362.                 {
  363.                         cl = 0x40;
  364.                         p+=12;
  365.                 }
  366.                 else if( __STRNICMP_LOCAL( p, "CONTEXT.", 8 ) == 0 )
  367.                 {
  368.                         cl = 0x80;
  369.                         p+=8;
  370.                 }
  371.                 else if( __STRNICMP_LOCAL( p, "PRIVATE.", 8 ) == 0 )
  372.                 {
  373.                         cl = 0xC0;
  374.                         p+=8;
  375.                 }
  376.                 if( __STRNICMP_LOCAL( p, "OID.", 4 ) == 0 )
  377.                 {
  378.                         p+=4;
  379.                 }
  380.  
  381.                 q = p;
  382.                 nPieces = 1;
  383.                 while( *p )
  384.                 {
  385.                         if( *p == '.' )
  386.                         {
  387.                                 nPieces++;
  388.                         }
  389.                         p++;
  390.                 }
  391.  
  392.                 n = 0;
  393.                 b = 0;
  394.                 p = q;
  395.                 while( n < nPieces )
  396.                 {
  397.                         q = p;
  398.                         while( *p )
  399.                         {
  400.                                 if( *p == '.' )
  401.                                 {
  402.                                         break;
  403.                                 }
  404.                                 p++;
  405.                         }
  406.  
  407.                         l = 0;
  408.                         if( *p == '.' )
  409.                         {
  410.                                 *p = 0;
  411.                                 l = (unsigned long) atoi( q );
  412.                                 q = p+1;
  413.                                 p = q;
  414.                         }
  415.                         else
  416.                         {
  417.                                 l = (unsigned long) atoi( q );
  418.                                 q = p;
  419.                         }
  420.  
  421.                         /* Digit is in l. */
  422.                         if( n == 0 )
  423.                         {
  424.                                 b = 40 * ((unsigned char)l);
  425.                         }
  426.                         else if( n == 1 )
  427.                         {
  428.                                 b += ((unsigned char) l);
  429.                                 abBinary[nBinary++] = b;
  430.                         }
  431.                         else
  432.                         {
  433.                                 MakeBase128( l, 1 );
  434.                         }
  435.                         n++;
  436.                 }
  437.  
  438.                 if( fOutName != NULL )
  439.                 {
  440.                         fOut = fopen( fOutName, "wt" );
  441.                         if( fOut == NULL )
  442.                         {
  443.                                 fprintf(stderr,"Unable to open output file %s\n", fOutName );
  444.                                 return 33;
  445.                         }
  446.                 }
  447.                 else
  448.                 {
  449.                         fOut = stdout;
  450.                 }
  451.  
  452.                 if( nCHex )
  453.                 {
  454.                         fprintf(fOut,"\"\\x%02X\\x%02X", cl | 6, nBinary );
  455.                 }
  456.                 else
  457.                 {
  458.                         fprintf(fOut,"%02X %02X ", cl | 6, nBinary );
  459.                 }
  460.                 nn = 0;
  461.                 while( nn < nBinary )
  462.                 {
  463.                         unsigned char b = abBinary[nn++];
  464.                         if( nn == nBinary )
  465.                         {
  466.                                 if( nCHex )
  467.                                 {
  468.                                         fprintf(fOut,"\\x%02X\"\n", b );
  469.                                 }
  470.                                 else
  471.                                 {
  472.                                         fprintf(fOut,"%02X\n", b );
  473.                                 }
  474.                         }
  475.                         else
  476.                         {
  477.                                 if( nCHex )
  478.                                 {
  479.                                         fprintf(fOut,"\\x%02X", b );
  480.                                 }
  481.                                 else
  482.                                 {
  483.                                         fprintf(fOut,"%02X ", b );
  484.                                 }
  485.                         }
  486.                 }
  487.                 if( fOut != stdout )
  488.                 {
  489.                         fclose( fOut );
  490.                 }
  491.                 break;
  492.         }
  493.  
  494.         return 0;
  495. }
  496.  
  497. /* */
  498.  
  499.