/************************************************************************ ***** * trval.c *----------------------------------------------------------------------- ----- * (c)1996, David M. Balenson * Additional changes by Aram Perez, RSA Data Security, Inc. * These changes are: * Compile for Win95 using MS Visual C++, V.4.1 * Used ANSI function definitions * Capitalized some messages and added more descriptions. * Default is to print the types. * Changed definition of WIDTH to 16. ************************************************************************ *****/ #include #include #ifdef WIN32 #include #include #endif #define OK 0 #define NOTOK (-1) /* IDENTIFIER OCTET = TAG CLASS | FORM OF ENCODING | TAG NUMBER */ /* TAG CLASSES */ #define ID_CLASS 0xc0 /* bits 8 and 7 */ #define CLASS_UNIV 0x00 /* 0 = universal */ #define CLASS_APPL 0x40 /* 1 = application */ #define CLASS_CONT 0x80 /* 2 = context-specific */ #define CLASS_PRIV 0xc0 /* 3 = private */ /* FORM OF ENCODING */ #define ID_FORM 0x20 /* bit 6 */ #define FORM_PRIM 0x00 /* 0 = primitive */ #define FORM_CONS 0x20 /* 1 = constructed */ /* TAG NUMBERS */ #define ID_TAG 0x1f /* bits 5-1 */ #define PRIM_BOOL 0x01 /* Boolean */ #define PRIM_INT 0x02 /* Integer */ #define PRIM_BITS 0x03 /* Bit String */ #define PRIM_OCTS 0x04 /* Octet String */ #define PRIM_NULL 0x05 /* Null */ #define PRIM_OID 0x06 /* Object Identifier */ #define PRIM_ODE 0x07 /* Object Descriptor */ #define CONS_EXTN 0x08 /* External */ #define PRIM_REAL 0x09 /* Real */ #define PRIM_ENUM 0x0a /* Enumerated type */ #define PRIM_ENCR 0x0b /* Encrypted */ #define CONS_SEQ 0x10 /* SEQUENCE/SEQUENCE OF */ #define CONS_SET 0x11 /* SET/SET OF */ #define DEFN_NUMS 0x12 /* Numeric String */ #define DEFN_PRTS 0x13 /* Printable String */ #define DEFN_T61S 0x14 /* T.61 String */ #define DEFN_VTXS 0x15 /* Videotex String */ #define DEFN_IA5S 0x16 /* IA5 String */ #define DEFN_UTCT 0x17 /* UTCTime */ #define DEFN_GENT 0x18 /* Generalized Time */ #define DEFN_GFXS 0x19 /* Graphics string (ISO2375) */ #define DEFN_VISS 0x1a /* Visible string */ #define DEFN_GENS 0x1b /* General string */ #define DEFN_CHRS 0x1c /* Character string */ #define LEN_XTND 0x80 /* long or indefinite form */ #define LEN_SMAX 127 /* largest short form */ #define LEN_MASK 0x7f /* mask to get number of bytes in length */ #define LEN_INDF (-1) /* indefinite length */ int print_types = 1; int expand_cont = 0; /************************************************************************ ****/ int trval(FILE* fin, FILE* fout); int trval2(FILE *fp, unsigned char *enc, int len, int lev, int* rlen); int decode_len(FILE *fp, unsigned char *enc, int len); int do_prim(FILE *fp, int tag, unsigned char *enc, int len, int lev); int do_cons(FILE *fp, unsigned char *enc, int len, int lev, int *rlen); void main(int argc, char** argv) { int optflg = 1; int options = 0; FILE *fp; int r; while (--argc > 0) { argv++; if (optflg && *(argv)[0] == '-') { /* if (!strcmp(*argv,"-types")) print_types = 1; else */ if (!strcmp(*argv,"-notypes")) print_types = 0; else if (!strcmp(*argv,"-cont")) expand_cont = 1; else if (!strcmp(*argv,"-nocont")) expand_cont = 0; else { fprintf(stderr,"Unknown option: %s\n", *argv); /* fprintf(stderr,"Usage: trval [-[no]types|-[no]cont] []\n"); */ fprintf(stderr,"Usage: trval [-notypes|-[no]cont] []\n"); exit(1); } } else { optflg = 0; if ((fp = fopen(*argv,"rb")) == NULL) { fprintf(stderr,"trval: unable to open %s\n", *argv); continue; } r = trval(fp, stdout); fclose(fp); } } if (optflg) r = trval(stdin, stdout); exit(r); } int trval(FILE* fin, FILE* fout) { unsigned char *p; int maxlen; int len; int cc; int r; int rlen; maxlen = BUFSIZ; p = (unsigned char *)malloc(maxlen); len = 0; while ((cc = fgetc(fin)) != EOF) { if (len == maxlen) { maxlen += BUFSIZ; p = (unsigned char *)realloc(p, maxlen); } p[len++] = cc; } fprintf(fout, "", len); r = trval2(fout, p, len, 0, &rlen); fprintf(fout, "\n"); (void) free(p); return(r); } int trval2(FILE *fp, unsigned char *enc, int len, int lev, int* rlen) { int l, eid, elen, xlen, r, rlen2; if (len < 2) { fprintf(fp, "Missing ID and length octets (%d).\n", len); return(NOTOK); } fprintf(fp, "\n"); for (l=0; l len - 2) { fprintf(fp, "Extended length too long (%d > %d - 2).\n", xlen, len); return(NOTOK); } elen = decode_len(fp, enc+2, xlen); } if (elen > len - 2 - xlen) { fprintf(fp, "Length too long (%d > %d - 2 - %d).\n", elen, len, xlen); return(NOTOK); } switch(eid & ID_CLASS) { case CLASS_UNIV: fprintf(fp, "[UNIV "); break; case CLASS_APPL: fprintf(fp, "[APPL "); break; case CLASS_CONT: fprintf(fp, "[CONT "); break; case CLASS_PRIV: fprintf(fp, "[PRIV "); break; } fprintf(fp, "%d", eid & ID_TAG); if (print_types && ((eid & ID_CLASS) == CLASS_UNIV)) switch(eid & ID_TAG) { case PRIM_BOOL: fprintf(fp, " Boolean"); break; case PRIM_INT: fprintf(fp, " Integer"); break; case PRIM_BITS: fprintf(fp, " Bit String"); break; case PRIM_OCTS: fprintf(fp, " Octet String"); break; case PRIM_NULL: fprintf(fp, " Null"); break; case PRIM_OID: fprintf(fp, " Object Identifier"); break; case PRIM_ODE: fprintf(fp, " Object Descriptor"); break; case CONS_EXTN: fprintf(fp, " External"); break; case PRIM_REAL: fprintf(fp, " Real"); break; case PRIM_ENUM: fprintf(fp, " Enumerated type"); break; case PRIM_ENCR: fprintf(fp, " Encrypted"); break; case CONS_SEQ: fprintf(fp, " Sequence/Sequence Of"); break; case CONS_SET: fprintf(fp, " Set/Set Of"); break; case DEFN_NUMS: fprintf(fp, " Numeric String"); break; case DEFN_PRTS: fprintf(fp, " Printable String"); break; case DEFN_T61S: fprintf(fp, " T.61 String"); break; case DEFN_VTXS: fprintf(fp, " Videotex String"); break; case DEFN_IA5S: fprintf(fp, " IA5 String"); break; case DEFN_UTCT: fprintf(fp, " UTCTime"); break; case DEFN_GENT: fprintf(fp, " Generalized Time"); break; case DEFN_GFXS: fprintf(fp, " Graphics string (ISO2375)"); break; case DEFN_VISS: fprintf(fp, " Visible string"); break; case DEFN_GENS: fprintf(fp, " General string"); break; case DEFN_CHRS: fprintf(fp, " Character string"); break; default: fprintf(fp, " ???"); } fprintf(fp, "] "); if ((eid & ID_CLASS) == CLASS_CONT && expand_cont) { fprintf(fp, "<%d>", elen); r = trval2(fp, enc+2+xlen, elen, lev+1, &rlen2); *rlen = 2 + xlen + rlen2; } else { switch(eid & ID_FORM) { case FORM_PRIM: fprintf(fp, "Primitive ", elen); r = do_prim(fp, eid & ID_TAG, enc+2+xlen, elen, lev+1); *rlen = 2 + xlen + elen; break; case FORM_CONS: fprintf(fp, "Constructed ", elen); r = do_cons(fp, enc+2+xlen, elen, lev+1, &rlen2); *rlen = 2 + xlen + rlen2; break; } } return(r); } int decode_len(FILE *fp, unsigned char *enc, int len) { int rlen; int i; fprintf(fp, "%02x ", enc[0]); rlen = enc[0]; for (i=1; i