Subversion Repositories oidconverter

Rev

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

Rev Author Line No. Line
2 daniel-mar 1
/*###################################################################
2
###                                                               ###
3
### Object ID converter. Matthias Gaertner, 06/1999               ###
4
### Converted to plain 'C' 07/2001                                ###
5
###                                                               ###
6
### Enhanced version by Daniel Marschall, ViaThinkSoft 06/2011    ###
7
### -- NEW 1.2: 2.48 can also be encoded!                         ###
8
### -- NEW 1.2: UUIDs (128-bit) are now supported!                ###
9
###             (requires GMPLib)                                 ###
10
### -- NEW 1.3: Length can now have more than 1 byte              ###
11
### -- NEW 1.4: No command line limitation anymore.               ###
12
### -- AS WELL AS SEVERAL BUG FIXES                               ###
13
###                                                               ###
14
### To compile with gcc simply use:                               ###
15
###   gcc -O2 -o oid oid.c -lgmp -lm                              ###
16
###                                                               ###
17
### To compile using cl, use:                                     ###
18
###   cl -DWIN32 -O1 oid.c (+ include gmp library)                ###
19
###                                                               ###
20
### Freeware - do with it whatever you want.                      ###
21
### Use at your own risk. No warranty of any kind.                ###
22
###                                                               ###
23
###################################################################*/
24
/* $Version: 1.4$ */
25
 
26
// MINOR PROBLEMS:
27
// - A wrong error message is shown when trying to encode "-0.0" or "x"
28
 
29
// NICE TO HAVE:
30
// - makefile / linuxpackage
31
// - better make functions instead of putting everything in main() with fprintf...
32
 
33
// NICE TO HAVE (INFINITY-IDEA - NOT IMPORTANT):
34
// - Is it possible to detect integer overflows and therefore output errors?
35
 
36
// -------------------------------------------------------
37
 
38
// Allows OIDs which are bigger than "long"
39
// Compile with "gcc oid.c -lgmp -lm"
40
#define is_gmp
41
 
42
#include <stdio.h>
43
#include <string.h>
44
#include <stdlib.h>
45
 
46
#ifdef is_gmp
47
#include <gmp.h>
48
#endif
49
 
50
#include <stdbool.h>
51
 
52
#ifndef __STRNICMP_LOCAL
53
#ifdef WIN32
54
#define __STRNICMP_LOCAL strnicmp
55
#else
56
#define __STRNICMP_LOCAL strncasecmp
57
#endif
58
#endif
59
 
60
// char abCommandLine[4096];
61
const unsigned int CLI_INITIAL_SIZE = 1024;
62
const unsigned int CLI_EXPANSION_SIZE = 1024;
63
unsigned int cli_size;
64
char * abCommandLine;
65
 
66
// unsigned char abBinary[128];
67
const unsigned int ABB_INITIAL_SIZE = 1024;
68
const unsigned int ABB_EXPANSION_SIZE = 1024;
69
unsigned int abb_size;
70
unsigned char * abBinary;
71
 
72
unsigned int    nBinary = 0;
73
 
74
 
75
#ifdef is_gmp
76
static void MakeBase128( mpz_t l, int first ) {
77
        if ( mpz_cmp_si(l, 127) > 0 ) {
78
                mpz_t l2;
79
                mpz_init(l2);
80
                mpz_div_ui(l2, l, 128);
81
                MakeBase128( l2 , 0 );
82
        }
83
        mpz_mod_ui(l, l, 128);
84
 
85
        if (nBinary+1 >= abb_size) {
86
                abb_size += ABB_EXPANSION_SIZE;
87
                abBinary = (unsigned char*) realloc(abBinary, abb_size);
88
                if (abBinary == NULL) {
89
                        fprintf(stderr, "Memory reallocation failure!\n");
90
                        exit(EXIT_FAILURE);
91
                }
92
        }
93
 
94
        if ( first ) {
95
                abBinary[nBinary++] = mpz_get_ui(l);
96
        } else {
97
                abBinary[nBinary++] = 0x80 | mpz_get_ui(l);
98
        }
99
}
100
#else
101
static void MakeBase128( unsigned long l, int first ) {
102
        if ( l > 127 ) {
103
                MakeBase128( l / 128, 0 );
104
        }
105
        l %= 128;
106
 
107
        if (nBinary+1 >= abb_size) {
108
                abb_size += ABB_EXPANSION_SIZE;
109
                abBinary = (unsigned char*) realloc(abBinary, abb_size);
110
                if (abBinary == NULL) {
111
                        fprintf(stderr, "Memory reallocation failure!\n");
112
                        exit(EXIT_FAILURE);
113
                }
114
        }
115
 
116
        if ( first ) {
117
                abBinary[nBinary++] = (unsigned char)l;
118
        } else {
119
                abBinary[nBinary++] = 0x80 | (unsigned char)l;
120
        }
121
}
122
#endif
123
 
124
int main( int argc, char **argv ) {
125
        cli_size = CLI_INITIAL_SIZE;
126
        abCommandLine  = (char*) malloc(cli_size * sizeof(char*));
127
        if (abCommandLine == NULL) {
128
                fprintf(stderr, "Memory allocation failure!\n");
129
                return EXIT_FAILURE;
130
        }
131
 
132
        abb_size = ABB_INITIAL_SIZE;
133
        abBinary  = (unsigned char*) malloc(abb_size * sizeof(unsigned char*));
134
        if (abBinary == NULL) {
135
                fprintf(stderr, "Memory allocation failure!\n");
136
                return EXIT_FAILURE;
137
        }
138
 
139
 
140
        char *fOutName = NULL;
141
        char *fInName = NULL;
142
        FILE *fOut = NULL;
143
 
144
        int n = 1;
145
        int nMode = 0;  /* dotted->hex */
146
        int nCHex = 0;
147
        int nAfterOption = 0;
148
 
149
        if ( argc == 1 ) {
150
                fprintf( stderr,
151
                "OID encoder/decoder 1.4 - Matthias Gaertner 1999/2001, Daniel Marschall 2011 - Freeware\n"
152
                #ifdef is_gmp
153
                "GMP Edition\n"
154
                #endif
155
                "\nUsage:\n"
156
                " OID [-C] [-o<outfile>] {-i<infile>|2.999.1}\n"
157
                "   converts dotted form to ASCII HEX DER output.\n"
158
                " OID -x [-o<outfile>] {-i<infile>|hex-digits}\n"
159
                "   decodes ASCII HEX DER and gives dotted form.\n" );
160
                return 1;
161
        }
162
 
163
        while ( n < argc ) {
164
                if ( !nAfterOption && argv[n][0] == '-' ) {
165
                        if ( argv[n][1] == 'x' ) {
166
                                nMode = 1;      /* hex->dotted */
167
                                if ( argv[n][2] != '\0' ) {
168
                                        argv[n--] += 2;
169
                                        nAfterOption = 1;
170
                                }
171
                        } else if ( argv[n][1] == 'C' ) {
172
                                nMode = 0;
173
                                nCHex = 1;
174
 
175
                                if ( argv[n][2] != '\0' ) {
176
                                        argv[n--] += 2;
177
                                        nAfterOption = 1;
178
                                }
179
                        } else if ( argv[n][1] == 'o' ) {
180
                                if ( argv[n][2] != '\0' ) {
181
                                        fOutName = &argv[n][2];
182
                                } else if ( n < argc-1 ) {
183
                                        fOutName = argv[++n];
184
                                } else {
185
                                        fprintf(stderr,"Incomplete command line.\n");
186
                                }
187
                        } else if ( argv[n][1] == 'i' ) {
188
                                if ( argv[n][2] != '\0' ) {
189
                                        fInName = &argv[n][2];
190
                                } else if ( n < argc-1 ) {
191
                                        fInName = argv[++n];
192
                                } else {
193
                                        fprintf(stderr,"Incomplete command line.\n");
194
                                }
195
                        }
196
                } else {
197
                        if ( fInName != NULL ) {
198
                                break;
199
                        }
200
 
201
                        nAfterOption = 1;
202
                        if ( strlen( argv[n] ) + strlen( abCommandLine ) >= sizeof(abCommandLine)-2 ) {
203
                                // fprintf(stderr,"Command line too long.\n");
204
                                // return 2;
205
 
206
                                cli_size += CLI_EXPANSION_SIZE + strlen( argv[n] ) + 1; // 1 = "."
207
                                abCommandLine = (char*) realloc(abCommandLine, cli_size);
208
                                if (abCommandLine == NULL) {
209
                                        fprintf(stderr, "Memory reallocation failure!\n");
210
                                        return EXIT_FAILURE;
211
                                }
212
                                // TODO: (Unklar) Wer garantiert, dass es mit "\0" abschließt?
213
                        }
214
                        strcat( abCommandLine, argv[n] );
215
                        if ( n != argc - 1 && nMode != 1 ) {
216
                                strcat( abCommandLine, "." );
217
                        }
218
                }
219
                n++;
220
        }
221
 
222
        if ( fInName != NULL && nMode == 1 ) {
223
                FILE *fIn = fopen( fInName, "rb" );
224
                size_t nRead = 0;
225
                if ( fIn == NULL ) {
226
                        fprintf(stderr,"Unable to open input file %s.\n", fInName );
227
                        return 11;
228
                }
229
                nRead = fread( abCommandLine, 1, sizeof(abCommandLine), fIn );
230
                abCommandLine[nRead] = '\0';
231
                fclose( fIn );
232
        } else if ( fInName != NULL && nMode == 0 ) {
233
                FILE *fIn = fopen( fInName, "rt" );
234
                if ( fIn == NULL ) {
235
                        fprintf(stderr,"Unable to open input file %s.\n", fInName );
236
                        return 11;
237
                }
238
                fgets( abCommandLine, sizeof(abCommandLine), fIn );
239
                fclose( fIn );
240
        }
241
 
242
        while ( nMode == 1 )    /* better if */
243
        {
244
                /* hex->dotted */
245
                /*printf("Hex-In: %s\n", abCommandLine );*/
246
 
247
                char *p = abCommandLine;
248
                char *q = p;
249
 
250
                unsigned char *pb = NULL;
251
                unsigned int nn = 0;
252
                #ifdef is_gmp
253
                mpz_t ll;
254
                mpz_init(ll);
255
                #else
256
                unsigned long ll = 0;
257
                #endif
258
                bool fOK = false;
259
                int fSub = 0; // Subtract value from next number output. Used when encoding {2 48} and up
260
 
261
                while ( *p ) {
262
                        if ( *p != '.' && *p != '\r' && *p != '\n' && *p != '\x20' && *p != '\t') {
263
                                *q++ = *p;
264
                        }
265
                        p++;
266
                }
267
                *q = '\0';
268
 
269
                if ( strlen( abCommandLine ) % 2 != 0 ) {
270
                        fprintf(stderr, "Encoded OID must have even number of hex digits!\n" );
271
                        return 2;
272
                }
273
 
274
                if ( strlen( abCommandLine ) < 3 ) {
275
                        fprintf(stderr, "Encoded OID must have at least three bytes!\n" );
276
                        return 2;
277
                }
278
 
279
                nBinary = 0;
280
                p = abCommandLine;
281
 
282
                while ( *p ) {
283
                        unsigned char b;
284
 
285
                        // Interpret upper nibble
286
                        if ( p[0] >= 'A' && p[0] <= 'F' ) {
287
                                b = (p[0] - 'A' + 10) * 16;
288
                        } else if ( p[0] >= 'a' && p[0] <= 'f' ) {
289
                                b = (p[0] - 'a' + 10) * 16;
290
                        } else if ( p[0] >= '0' && p[0] <= '9' ) {
291
                                b = (p[0] - '0') * 16;
292
                        } else {
293
                                fprintf(stderr, "Must have hex digits only!\n" );
294
                                return 2;
295
                        }
296
 
297
                        // Interpret lower nibble
298
                        if ( p[1] >= 'A' && p[1] <= 'F' ) {
299
                                b += (p[1] - 'A' + 10);
300
                        } else if ( p[1] >= 'a' && p[1] <= 'f' ) {
301
                                b += (p[1] - 'a' + 10);
302
                        } else if ( p[1] >= '0' && p[1] <= '9' ) {
303
                                b += (p[1] - '0');
304
                        } else {
305
                                fprintf(stderr, "Must have hex digits only!\n" );
306
                                return 2;
307
                        }
308
 
309
                        if (nBinary+1 >= abb_size) {
310
                                abb_size += ABB_EXPANSION_SIZE;
311
                                abBinary = (unsigned char*) realloc(abBinary, abb_size);
312
                                if (abBinary == NULL) {
313
                                        fprintf(stderr, "Memory reallocation failure!\n");
314
                                        return EXIT_FAILURE;
315
                                }
316
                        }
317
 
318
                        abBinary[nBinary++] = b;
319
                        p += 2;
320
                }
321
 
322
                /*printf("Hex-In: %s\n", abCommandLine );*/
323
 
324
                if ( fOutName != NULL ) {
325
                        fOut = fopen( fOutName, "wt" );
326
                        if ( fOut == NULL ) {
327
                                fprintf(stderr,"Unable to open output file %s\n", fOutName );
328
                                return 33;
329
                        }
330
                } else {
331
                        fOut = stdout;
332
                }
333
 
334
                pb = abBinary;
335
                nn = 0;
336
                #ifdef is_gmp
337
                mpz_init(ll);
338
                #else
339
                ll = 0;
340
                #endif
341
                fOK = false;
342
                fSub = 0;
343
 
344
                // 0 = Universal Class Identifier Tag
345
                // 1 = Length part (may have more than 1 byte!)
346
                // 2 = First two arc encoding
347
                // 3 = Encoding of arc three and higher
348
                unsigned char part = 0;
349
 
350
                unsigned char lengthbyte_count = 0;
351
                unsigned char lengthbyte_pos = 0;
352
                bool lengthfinished = false;
353
 
354
                while ( nn < nBinary ) {
355
                        if ( part == 0 ) { // Class Tag
356
                                unsigned char cl = ((*pb & 0xC0) >> 6) & 0x03;
357
                                switch ( cl ) {
358
                                        default:
359
                                        case 0: fprintf(fOut,"UNIVERSAL"); break;
360
                                        case 1: fprintf(fOut,"APPLICATION"); break;
361
                                        case 2: fprintf(fOut,"CONTEXT"); break;
362
                                        case 3: fprintf(fOut,"PRIVATE"); break;
363
                                }
364
                                fprintf(fOut," OID");
365
                                part++;
366
                        } else if ( part == 1 ) { // Length
367
 
368
                                // Find out the length and save it into ll
369
 
370
                                // 2nd Byte
371
                                // 0x00 .. 0x7F => The actual length
372
                                // 0x80 + n => The length is spread over the following 'n' bytes
373
                                // (Unknown: Is 'n' limited or can it be until 0xFF is reached?)
374
                                // (Unknown: How is length=0x80 (=0 following bytes define the length) defined? Is it the same as 0x00?)
375
 
376
                                if (nn == 1) { // The first length byte
377
                                        lengthbyte_pos = 0;
378
                                        if ( (*pb & 0x80) != 0 ) {
379
                                                // 0x80 + n => The length is spread over the following 'n' bytes
380
                                                lengthfinished = false;
381
                                                lengthbyte_count = *pb & 0x7F;
382
                                                fOK = false;
383
                                        } else {
384
                                                // 0x00 .. 0x7F => The actual length
385
                                                #ifdef is_gmp
386
                                                mpz_set_ui(ll, *pb);
387
                                                #else
388
                                                ll = *pb;
389
                                                #endif
390
                                                lengthfinished = true;
391
                                                lengthbyte_count = 0;
392
                                                fOK = true;
393
                                        }
394
                                } else {
395
                                        if (lengthbyte_count > lengthbyte_pos) {
396
                                                #ifdef is_gmp
397
                                                mpz_mul_ui(ll, ll, 0x100);
398
                                                mpz_add_ui(ll, ll, *pb);
399
                                                #else
400
                                                ll *= 0x100;
401
                                                ll += *pb;
402
                                                #endif
403
                                                lengthbyte_pos++;
404
                                        }
405
 
406
                                        if (lengthbyte_count == lengthbyte_pos) {
407
                                                lengthfinished = true;
408
                                                fOK = true;
409
                                        }
410
                                }
411
 
412
                                if (lengthfinished) { // The length is now in ll
413
                                        #ifdef is_gmp
414
                                        if ( mpz_cmp_ui(ll,  nBinary - 2 - lengthbyte_count) != 0 ) {
415
                                                fprintf(fOut,"\n");
416
                                                if ( fOut != stdout ) {
417
                                                        fclose( fOut );
418
                                                }
419
                                                fprintf(stderr,"\nInvalid length (%d entered, but %s expected)\n", nBinary - 2, mpz_get_str(NULL, 10, ll) );
420
                                                return 3;
421
                                        }
422
                                        mpz_set_ui(ll, 0); // reset for later usage
423
                                        #else
424
                                        if ( ll != nBinary - 2 - lengthbyte_count ) {
425
                                                fprintf(fOut,"\n");
426
                                                if ( fOut != stdout ) {
427
                                                        fclose( fOut );
428
                                                }
429
                                                fprintf(stderr,"\nInvalid length (%d entered, but %d expected)\n", nBinary - 2, ll );
430
                                                return 3;
431
                                        }
432
                                        ll = 0; // reset for later usage
433
                                        #endif
434
                                        fOK = true;
435
                                        part++;
436
                                }
437
                        } else if ( part == 2 ) { // First two arcs
438
                                int first = *pb / 40;
439
                                int second = *pb % 40;
440
                                if (first > 2) {
441
                                        first = 2;
442
                                        fprintf(fOut,".%d", first );
443
 
444
                                        if ( (*pb & 0x80) != 0 ) {
445
                                                // 2.48 and up => 2+ octets
446
                                                #ifdef is_gmp
447
                                                mpz_add_ui(ll, ll, (*pb & 0x7F));
448
                                                #else
449
                                                ll += (*pb & 0x7F);
450
                                                #endif
451
                                                fSub = 80;
452
                                                fOK = false;
453
                                        } else {
454
                                                // 2.0 till 2.47 => 1 octet
455
                                                second = *pb - 80;
456
                                                fprintf(fOut,".%d",second);
457
                                                fOK = true;
458
                                                #ifdef is_gmp
459
                                                mpz_set_ui(ll, 0);
460
                                                #else
461
                                                ll = 0;
462
                                                #endif
463
                                        }
464
                                } else {
465
                                        // 0.0 till 0.37 => 1 octet
466
                                        // 1.0 till 1.37 => 1 octet
467
                                        fprintf(fOut,".%d.%d", first, second );
468
                                        fOK = true;
469
                                        #ifdef is_gmp
470
                                        mpz_set_ui(ll, 0);
471
                                        #else
472
                                        ll = 0;
473
                                        #endif
474
                                }
475
                                part++;
476
                        } else if ( part == 3 ) { // Arc three and higher
477
                                if ( (*pb & 0x80) != 0 ) {
478
                                        #ifdef is_gmp
479
                                        mpz_mul_ui(ll, ll, 128);
480
                                        mpz_add_ui(ll, ll, (*pb & 0x7F));
481
                                        #else
482
                                        ll *= 128;
483
                                        ll += (*pb & 0x7F);
484
                                        #endif
485
                                        fOK = false;
486
                                } else {
487
                                        #ifdef is_gmp
488
                                        mpz_mul_ui(ll, ll, 128);
489
                                        mpz_add_ui(ll, ll, *pb);
490
                                        mpz_sub_ui(ll, ll, fSub);
491
                                        fprintf(fOut,".%s", mpz_get_str(NULL, 10, ll) );
492
                                        mpz_set_ui(ll, 0);
493
                                        #else
494
                                        ll *= 128;
495
                                        ll += *pb;
496
                                        ll -= fSub;
497
                                        fprintf(fOut,".%lu", ll );
498
                                        ll = 0;
499
                                        #endif
500
                                        fSub = 0;
501
                                        fOK = true;
502
                                }
503
                        }
504
 
505
                        pb++;
506
                        nn++;
507
                }
508
 
509
                if ( !fOK ) {
510
                        fprintf(fOut,"\n");
511
                        if ( fOut != stdout ) {
512
                                fclose( fOut );
513
                        }
514
                        fprintf(stderr,"\nEncoding error. The OID is not constructed properly.\n");
515
                        return 4;
516
                } else {
517
                        fprintf(fOut,"\n");
518
                }
519
 
520
                if ( fOut != stdout ) {
521
                        fclose( fOut );
522
                }
523
                break;
524
        };
525
 
526
        while ( nMode == 0 )    /* better if */
527
        {
528
                /* dotted->hex */
529
                /* printf("OID.%s\n", abCommandLine ); */
530
 
531
                char *p = abCommandLine;
532
                unsigned char cl = 0x00;
533
                char *q = NULL;
534
                int nPieces = 1;
535
                int n = 0;
536
                unsigned char b = 0;
537
                unsigned int nn = 0;
538
                #ifdef is_gmp
539
                mpz_t l;
540
                #else
541
                unsigned long l = 0;
542
                #endif
543
                bool isjoint = false;
544
 
545
                if ( __STRNICMP_LOCAL( p, "UNIVERSAL.", 10 ) == 0 ) {
546
                        p+=10;
547
                } else if ( __STRNICMP_LOCAL( p, "APPLICATION.", 12 ) == 0 ) {
548
                        cl = 0x40;
549
                        p+=12;
550
                } else if ( __STRNICMP_LOCAL( p, "CONTEXT.", 8 ) == 0 ) {
551
                        cl = 0x80;
552
                        p+=8;
553
                } else if ( __STRNICMP_LOCAL( p, "PRIVATE.", 8 ) == 0 ) {
554
                        cl = 0xC0;
555
                        p+=8;
556
                }
557
 
558
                if ( __STRNICMP_LOCAL( p, "OID.", 4 ) == 0 ) {
559
                        p+=4;
560
                }
561
 
562
                q = p;
563
                nPieces = 1;
564
                while ( *p ) {
565
                        if ( *p == '.' ) {
566
                                nPieces++;
567
                        }
568
                        p++;
569
                }
570
 
571
                n = 0;
572
                b = 0;
573
                p = q;
574
                while ( n < nPieces ) {
575
                        q = p;
576
                        while ( *p ) {
577
                                if ( *p == '.' ) {
578
                                        break;
579
                                }
580
                                p++;
581
                        }
582
 
583
                        #ifdef is_gmp
584
                        mpz_init(l);
585
                        #else
586
                        l = 0;
587
                        #endif
588
                        if ( *p == '.' ) {
589
                                *p = 0;
590
                                #ifdef is_gmp
591
                                mpz_set_str(l, q, 10);
592
                                #else
593
                                l = (unsigned long) atoi( q );
594
                                #endif
595
                                q = p+1;
596
                                p = q;
597
                        } else {
598
                                #ifdef is_gmp
599
                                mpz_set_str(l, q, 10);
600
                                #else
601
                                l = (unsigned long) atoi( q );
602
                                #endif
603
                                q = p;
604
                        }
605
 
606
                        /* Digit is in l. */
607
                        if ( n == 0 ) {
608
                                #ifdef is_gmp
609
                                if (mpz_cmp_ui(l, 2) > 0) {
610
                                #else
611
                                if (l > 2) {
612
                                #endif
613
                                        fprintf(stderr,"\nEncoding error. The top arc is limited to 0, 1 and 2.\n");
614
                                        return 5;
615
                                }
616
                                #ifdef is_gmp
617
                                b += 40 * mpz_get_ui(l);
618
                                isjoint = mpz_cmp_ui(l, 2) == 0;
619
                                #else
620
                                b = 40 * ((unsigned char)l);
621
                                isjoint = l == 2;
622
                                #endif
623
                        } else if ( n == 1 ) {
624
                                #ifdef is_gmp
625
                                if ((mpz_cmp_ui(l, 39) > 0) && (!isjoint)) {
626
                                #else
627
                                if ((l > 39) && (!isjoint)) {
628
                                #endif
629
                                        fprintf(stderr,"\nEncoding error. The second level is limited to 0..39 for top level arcs 0 and 1.\n");
630
                                        return 5;
631
                                }
632
 
633
                                #ifdef is_gmp
634
                                if (mpz_cmp_ui(l, 47) > 0) {
635
                                        mpz_add_ui(l, l, 80);
636
                                        MakeBase128( l, 1 );
637
                                } else {
638
                                        b += mpz_get_ui(l);
639
                                        if (nBinary+1 >= abb_size) {
640
                                                abb_size += ABB_EXPANSION_SIZE;
641
                                                abBinary = (unsigned char*) realloc(abBinary, abb_size);
642
                                                if (abBinary == NULL) {
643
                                                        fprintf(stderr, "Memory reallocation failure!\n");
644
                                                        return EXIT_FAILURE;
645
                                                }
646
                                        }
647
                                        abBinary[nBinary++] = b;
648
                                }
649
                                #else
650
                                if (l > 47) {
651
                                        l += 80;
652
                                        MakeBase128( l, 1 );
653
                                } else {
654
                                        b += ((unsigned char) l);
655
                                        if (nBinary+1 >= abb_size) {
656
                                                abb_size += ABB_EXPANSION_SIZE;
657
                                                abBinary = (unsigned char*) realloc(abBinary, abb_size);
658
                                                if (abBinary == NULL) {
659
                                                        fprintf(stderr, "Memory reallocation failure!\n");
660
                                                        return EXIT_FAILURE;
661
                                                }
662
                                        }
663
                                        abBinary[nBinary++] = b;
664
                                }
665
                                #endif
666
                        } else {
667
                                MakeBase128( l, 1 );
668
                        }
669
                        n++;
670
                }
671
 
672
                if (n < 2) {
673
                        fprintf(stderr,"\nEncoding error. The minimum depth of an encodeable OID is 2. (e.g. 2.999)\n");
674
                        return 5;
675
                }
676
 
677
                if ( fOutName != NULL ) {
678
                        fOut = fopen( fOutName, "wt" );
679
                        if ( fOut == NULL ) {
680
                                fprintf(stderr,"Unable to open output file %s\n", fOutName );
681
                                return 33;
682
                        }
683
                } else {
684
                        fOut = stdout;
685
                }
686
 
687
                if ( nCHex ) {
688
                        fprintf(fOut,"\"\\x%02X\\x%02X", cl | 6, nBinary );
689
                } else {
690
                        fprintf(fOut,"%02X %02X ", cl | 6, nBinary );
691
                }
692
                nn = 0;
693
                while ( nn < nBinary ) {
694
                        unsigned char b = abBinary[nn++];
695
                        if ( nn == nBinary ) {
696
                                if ( nCHex ) {
697
                                        fprintf(fOut,"\\x%02X\"\n", b );
698
                                } else {
699
                                        fprintf(fOut,"%02X\n", b );
700
                                }
701
                        } else {
702
                                if ( nCHex ) {
703
                                        fprintf(fOut,"\\x%02X", b );
704
                                } else {
705
                                        fprintf(fOut,"%02X ", b );
706
                                }
707
                        }
708
                }
709
                if ( fOut != stdout ) {
710
                        fclose( fOut );
711
                }
712
                break;
713
        }
714
 
715
        free(abCommandLine);
716
        free(abBinary);
717
 
718
        return 0;
719
}
720
 
721
/* */
722