Path: blob/main/crypto/krb5/src/tests/asn.1/trval.c
34907 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright (C) 1992,1993 Trusted Information Systems, Inc.3*4* Permission to include this software in the Kerberos V5 distribution5* was graciously provided by Trusted Information Systems.6*7* Trusted Information Systems makes no representation about the8* suitability of this software for any purpose. It is provided9* "as is" without express or implied warranty.10*/11/*12* Copyright (C) 1994 Massachusetts Institute of Technology13*14* Export of this software from the United States of America may15* require a specific license from the United States Government.16* It is the responsibility of any person or organization contemplating17* export to obtain such a license before exporting.18*19* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and20* distribute this software and its documentation for any purpose and21* without fee is hereby granted, provided that the above copyright22* notice appear in all copies and that both that copyright notice and23* this permission notice appear in supporting documentation, and that24* the name of M.I.T. not be used in advertising or publicity pertaining25* to distribution of the software without specific, written prior26* permission. Furthermore if you modify this software you must label27* your software as modified software and not distribute it in such a28* fashion that it might be confused with the original M.I.T. software.29* M.I.T. makes no representations about the suitability of30* this software for any purpose. It is provided "as is" without express31* or implied warranty.32*/3334/*****************************************************************************35* trval.c.c36*****************************************************************************/3738#include <unistd.h>39#include <stdlib.h>40#include <stdio.h>41#include <ctype.h>42#include <string.h>4344#define OK 045#define NOTOK (-1)4647/* IDENTIFIER OCTET = TAG CLASS | FORM OF ENCODING | TAG NUMBER */4849/* TAG CLASSES */50#define ID_CLASS 0xc0 /* bits 8 and 7 */51#define CLASS_UNIV 0x00 /* 0 = universal */52#define CLASS_APPL 0x40 /* 1 = application */53#define CLASS_CONT 0x80 /* 2 = context-specific */54#define CLASS_PRIV 0xc0 /* 3 = private */5556/* FORM OF ENCODING */57#define ID_FORM 0x20 /* bit 6 */58#define FORM_PRIM 0x00 /* 0 = primitive */59#define FORM_CONS 0x20 /* 1 = constructed */6061/* TAG NUMBERS */62#define ID_TAG 0x1f /* bits 5-1 */63#define PRIM_BOOL 0x01 /* Boolean */64#define PRIM_INT 0x02 /* Integer */65#define PRIM_BITS 0x03 /* Bit String */66#define PRIM_OCTS 0x04 /* Octet String */67#define PRIM_NULL 0x05 /* Null */68#define PRIM_OID 0x06 /* Object Identifier */69#define PRIM_ODE 0x07 /* Object Descriptor */70#define CONS_EXTN 0x08 /* External */71#define PRIM_REAL 0x09 /* Real */72#define PRIM_ENUM 0x0a /* Enumerated type */73#define PRIM_ENCR 0x0b /* Encrypted */74#define PRIM_UTF8 0x0c /* UTF8String */75#define CONS_SEQ 0x10 /* SEQUENCE/SEQUENCE OF */76#define CONS_SET 0x11 /* SET/SET OF */77#define DEFN_NUMS 0x12 /* Numeric String */78#define DEFN_PRTS 0x13 /* Printable String */79#define DEFN_T61S 0x14 /* T.61 String */80#define DEFN_VTXS 0x15 /* Videotex String */81#define DEFN_IA5S 0x16 /* IA5 String */82#define DEFN_UTCT 0x17 /* UTCTime */83#define DEFN_GENT 0x18 /* Generalized Time */84#define DEFN_GFXS 0x19 /* Graphics string (ISO2375) */85#define DEFN_VISS 0x1a /* Visible string */86#define DEFN_GENS 0x1b /* General string */87#define DEFN_CHRS 0x1c /* Character string */8889#define LEN_XTND 0x80 /* long or indefinite form */90#define LEN_SMAX 127 /* largest short form */91#define LEN_MASK 0x7f /* mask to get number of bytes in length */92#define LEN_INDF (-1) /* indefinite length */9394#define KRB5 /* Do krb5 application types */9596int print_types = 0;97int print_id_and_len = 1;98int print_constructed_length = 1;99int print_primitive_length = 1;100int print_skip_context = 0;101int print_skip_tagnum = 1;102int print_context_shortcut = 0;103int do_hex = 0;104#ifdef KRB5105int print_krb5_types = 0;106#endif107108int current_appl_type = -1;109110int decode_len (FILE *, unsigned char *, int);111int do_prim (FILE *, int, unsigned char *, int, int);112int do_cons (FILE *, unsigned char *, int, int, int *);113int do_prim_bitstring (FILE *, int, unsigned char *, int, int);114int do_prim_int (FILE *, int, unsigned char *, int, int);115int do_prim_string (FILE *, int, unsigned char *, int, int);116void print_tag_type (FILE *, int, int);117int trval (FILE *, FILE *);118int trval2 (FILE *, unsigned char *, int, int, int *);119120121/****************************************************************************/122123static int124convert_nibble(int ch)125{126if (isdigit(ch))127return (ch - '0');128if (ch >= 'a' && ch <= 'f')129return (ch - 'a' + 10);130if (ch >= 'A' && ch <= 'F')131return (ch - 'A' + 10);132return -1;133}134135int136trval(FILE *fin, FILE *fout)137{138unsigned char *p;139unsigned int maxlen;140int len;141int cc, cc2, n1, n2;142int r;143int rlen;144145maxlen = BUFSIZ;146p = (unsigned char *)malloc(maxlen);147len = 0;148while ((cc = fgetc(fin)) != EOF) {149if ((unsigned int) len == maxlen) {150maxlen += BUFSIZ;151p = (unsigned char *)realloc(p, maxlen);152}153if (do_hex) {154if (cc == ' ' || cc == '\n' || cc == '\t')155continue;156cc2 = fgetc(fin);157if (cc2 == EOF)158break;159n1 = convert_nibble(cc);160n2 = convert_nibble(cc2);161cc = (n1 << 4) + n2;162}163p[len++] = cc;164}165fprintf(fout, "<%d>", len);166r = trval2(fout, p, len, 0, &rlen);167fprintf(fout, "\n");168(void) free(p);169return(r);170}171172int173trval2(FILE *fp, unsigned char *enc, int len, int lev, int *rlen)174{175int l, eid, elen, xlen, r, rlen2 = 0;176int rlen_ext = 0;177178r = OK;179*rlen = -1;180181if (len < 2) {182fprintf(fp, "missing id and length octets (%d)\n", len);183return(NOTOK);184}185186fprintf(fp, "\n");187for (l=0; l<lev; l++) fprintf(fp, ". ");188189context_restart:190eid = enc[0];191elen = enc[1];192193if (print_id_and_len) {194fprintf(fp, "%02x ", eid);195fprintf(fp, "%02x ", elen);196}197198if (elen == LEN_XTND) {199fprintf(fp,200"indefinite length encoding not implemented (0x%02x)\n", elen);201return(NOTOK);202}203204xlen = 0;205if (elen & LEN_XTND) {206xlen = elen & LEN_MASK;207if (xlen > len - 2) {208fprintf(fp, "extended length too long (%d > %d - 2)\n", xlen, len);209return(NOTOK);210}211elen = decode_len(fp, enc+2, xlen);212}213214if (elen > len - 2 - xlen) {215fprintf(fp, "length too long (%d > %d - 2 - %d)\n", elen, len, xlen);216return(NOTOK);217}218219print_tag_type(fp, eid, lev);220221if (print_context_shortcut && (eid & ID_CLASS) == CLASS_CONT &&222(eid & ID_FORM) == FORM_CONS && lev > 0) {223rlen_ext += 2 + xlen;224enc += 2 + xlen;225fprintf(fp, " ");226goto context_restart;227}228229switch(eid & ID_FORM) {230case FORM_PRIM:231r = do_prim(fp, eid & ID_TAG, enc+2+xlen, elen, lev+1);232*rlen = 2 + xlen + elen + rlen_ext;233break;234case FORM_CONS:235if (print_constructed_length) {236fprintf(fp, " constr");237fprintf(fp, " <%d>", elen);238}239r = do_cons(fp, enc+2+xlen, elen, lev+1, &rlen2);240*rlen = 2 + xlen + rlen2 + rlen_ext;241break;242}243244return(r);245}246247int248decode_len(FILE *fp, unsigned char *enc, int len)249{250int rlen;251int i;252253if (print_id_and_len)254fprintf(fp, "%02x ", enc[0]);255rlen = enc[0];256for (i=1; i<len; i++) {257if (print_id_and_len)258fprintf(fp, "%02x ", enc[i]);259rlen = (rlen * 0x100) + enc[i];260}261return(rlen);262}263264/*265* This is the printing function for bit strings266*/267int268do_prim_bitstring(FILE *fp, int tag, unsigned char *enc, int len, int lev)269{270int i;271long num = 0;272273if (tag != PRIM_BITS || len > 5)274return 0;275276for (i=1; i < len; i++) {277num = num << 8;278num += enc[i];279}280281fprintf(fp, " 0x%lx", num);282if (enc[0])283fprintf(fp, " (%d unused bits)", enc[0]);284return 1;285}286287/*288* This is the printing function for integers289*/290int291do_prim_int(FILE *fp, int tag, unsigned char *enc, int len, int lev)292{293int i;294long num = 0;295296if (tag != PRIM_INT || len > 4)297return 0;298299if (enc[0] & 0x80)300num = -1;301302for (i=0; i < len; i++) {303num = num << 8;304num += enc[i];305}306307fprintf(fp, " %ld", num);308return 1;309}310311312/*313* This is the printing function which we use if it's a string or314* other other type which is best printed as a string315*/316int317do_prim_string(FILE *fp, int tag, unsigned char *enc, int len, int lev)318{319int i;320321/*322* Only try this printing function with "reasonable" types323*/324if ((tag < DEFN_NUMS) && (tag != PRIM_OCTS) && (tag != PRIM_UTF8))325return 0;326327for (i=0; i < len; i++)328if (!isprint(enc[i]))329return 0;330fprintf(fp, " \"%.*s\"", len, enc);331return 1;332}333334int335do_prim(FILE *fp, int tag, unsigned char *enc, int len, int lev)336{337int n;338int i;339int j;340int width;341342if (do_prim_string(fp, tag, enc, len, lev))343return OK;344if (do_prim_int(fp, tag, enc, len, lev))345return OK;346if (do_prim_bitstring(fp, tag, enc, len, lev))347return OK;348349if (print_primitive_length)350fprintf(fp, " <%d>", len);351352width = (80 - (lev * 3) - 8) / 4;353354for (n = 0; n < len; n++) {355if ((n % width) == 0) {356fprintf(fp, "\n");357for (i=0; i<lev; i++) fprintf(fp, " ");358}359fprintf(fp, "%02x ", enc[n]);360if ((n % width) == (width-1)) {361fprintf(fp, " ");362for (i=n-(width-1); i<=n; i++)363if (isprint(enc[i])) fprintf(fp, "%c", enc[i]);364else fprintf(fp, ".");365}366}367if ((j = (n % width)) != 0) {368fprintf(fp, " ");369for (i=0; i<width-j; i++) fprintf(fp, " ");370for (i=n-j; i<n; i++)371if (isprint(enc[i])) fprintf(fp, "%c", enc[i]);372else fprintf(fp, ".");373}374return(OK);375}376377int378do_cons(FILE *fp, unsigned char *enc, int len, int lev, int *rlen)379{380int n;381int r = 0;382int rlen2;383int rlent;384int save_appl;385386save_appl = current_appl_type;387for (n = 0, rlent = 0; n < len; n+=rlen2, rlent+=rlen2) {388r = trval2(fp, enc+n, len-n, lev, &rlen2);389current_appl_type = save_appl;390if (r != OK) return(r);391}392if (rlent != len) {393fprintf(fp, "inconsistent constructed lengths (%d != %d)\n",394rlent, len);395return(NOTOK);396}397*rlen = rlent;398return(r);399}400401struct typestring_table {402int k1, k2;403char *str;404int new_appl;405};406407static char *408lookup_typestring(struct typestring_table *table, int key1, int key2)409{410struct typestring_table *ent;411412for (ent = table; ent->k1 > 0; ent++) {413if ((ent->k1 == key1) &&414(ent->k2 == key2)) {415if (ent->new_appl)416current_appl_type = ent->new_appl;417return ent->str;418}419}420return 0;421}422423424struct typestring_table univ_types[] = {425{ PRIM_BOOL, -1, "Boolean"},426{ PRIM_INT, -1, "Integer"},427{ PRIM_BITS, -1, "Bit String"},428{ PRIM_OCTS, -1, "Octet String"},429{ PRIM_NULL, -1, "Null"},430{ PRIM_OID, -1, "Object Identifier"},431{ PRIM_ODE, -1, "Object Descriptor"},432{ CONS_EXTN, -1, "External"},433{ PRIM_REAL, -1, "Real"},434{ PRIM_ENUM, -1, "Enumerated type"},435{ PRIM_ENCR, -1, "Encrypted"},436{ PRIM_UTF8, -1, "UTF8String"},437{ CONS_SEQ, -1, "Sequence/Sequence Of"},438{ CONS_SET, -1, "Set/Set Of"},439{ DEFN_NUMS, -1, "Numeric String"},440{ DEFN_PRTS, -1, "Printable String"},441{ DEFN_T61S, -1, "T.61 String"},442{ DEFN_VTXS, -1, "Videotex String"},443{ DEFN_IA5S, -1, "IA5 String"},444{ DEFN_UTCT, -1, "UTCTime"},445{ DEFN_GENT, -1, "Generalized Time"},446{ DEFN_GFXS, -1, "Graphics string (ISO2375)"},447{ DEFN_VISS, -1, "Visible string"},448{ DEFN_GENS, -1, "General string"},449{ DEFN_CHRS, -1, "Character string"},450{ -1, -1, 0}451};452453#ifdef KRB5454struct typestring_table krb5_types[] = {455{ 1, -1, "Krb5 Ticket"},456{ 2, -1, "Krb5 Authenticator"},457{ 3, -1, "Krb5 Encrypted ticket part"},458{ 10, -1, "Krb5 AS-REQ packet"},459{ 11, -1, "Krb5 AS-REP packet"},460{ 12, -1, "Krb5 TGS-REQ packet"},461{ 13, -1, "Krb5 TGS-REP packet"},462{ 14, -1, "Krb5 AP-REQ packet"},463{ 15, -1, "Krb5 AP-REP packet"},464{ 20, -1, "Krb5 SAFE packet"},465{ 21, -1, "Krb5 PRIV packet"},466{ 22, -1, "Krb5 CRED packet"},467{ 30, -1, "Krb5 ERROR packet"},468{ 25, -1, "Krb5 Encrypted AS-REP part"},469{ 26, -1, "Krb5 Encrypted TGS-REP part"},470{ 27, -1, "Krb5 Encrypted AP-REP part"},471{ 28, -1, "Krb5 Encrypted PRIV part"},472{ 29, -1, "Krb5 Encrypted CRED part"},473{ -1, -1, 0}474};475476struct typestring_table krb5_fields[] = {477{ 1000, 0, "name-type"}, /* PrincipalName */478{ 1000, 1, "name-string"},479480{ 1001, 0, "etype"}, /* Encrypted data */481{ 1001, 1, "kvno"},482{ 1001, 2, "cipher"},483484{ 1002, 0, "addr-type"}, /* HostAddress */485{ 1002, 1, "address"},486487{ 1003, 0, "addr-type"}, /* HostAddresses */488{ 1003, 1, "address"},489490{ 1004, 0, "ad-type"}, /* AuthorizationData */491{ 1004, 1, "ad-data"},492493{ 1005, 0, "keytype"}, /* EncryptionKey */494{ 1005, 1, "keyvalue"},495496{ 1006, 0, "cksumtype"}, /* Checksum */497{ 1006, 1, "checksum"},498499{ 1007, 0, "kdc-options"}, /* KDC-REQ-BODY */500{ 1007, 1, "cname", 1000},501{ 1007, 2, "realm"},502{ 1007, 3, "sname", 1000},503{ 1007, 4, "from"},504{ 1007, 5, "till"},505{ 1007, 6, "rtime"},506{ 1007, 7, "nonce"},507{ 1007, 8, "etype"},508{ 1007, 9, "addresses", 1003},509{ 1007, 10, "enc-authorization-data", 1001},510{ 1007, 11, "additional-tickets"},511512{ 1008, 1, "padata-type"}, /* PA-DATA */513{ 1008, 2, "pa-data"},514515{ 1009, 0, "user-data"}, /* KRB-SAFE-BODY */516{ 1009, 1, "timestamp"},517{ 1009, 2, "usec"},518{ 1009, 3, "seq-number"},519{ 1009, 4, "s-address", 1002},520{ 1009, 5, "r-address", 1002},521522{ 1010, 0, "lr-type"}, /* LastReq */523{ 1010, 1, "lr-value"},524525{ 1011, 0, "key", 1005}, /* KRB-CRED-INFO */526{ 1011, 1, "prealm"},527{ 1011, 2, "pname", 1000},528{ 1011, 3, "flags"},529{ 1011, 4, "authtime"},530{ 1011, 5, "startime"},531{ 1011, 6, "endtime"},532{ 1011, 7, "renew-till"},533{ 1011, 8, "srealm"},534{ 1011, 9, "sname", 1000},535{ 1011, 10, "caddr", 1002},536537{ 1, 0, "tkt-vno"}, /* Ticket */538{ 1, 1, "realm"},539{ 1, 2, "sname", 1000},540{ 1, 3, "tkt-enc-part", 1001},541542{ 2, 0, "authenticator-vno"}, /* Authenticator */543{ 2, 1, "crealm"},544{ 2, 2, "cname", 1000},545{ 2, 3, "cksum", 1006},546{ 2, 4, "cusec"},547{ 2, 5, "ctime"},548{ 2, 6, "subkey", 1005},549{ 2, 7, "seq-number"},550{ 2, 8, "authorization-data", 1004},551552{ 3, 0, "flags"}, /* EncTicketPart */553{ 3, 1, "key", 1005},554{ 3, 2, "crealm"},555{ 3, 3, "cname", 1000},556{ 3, 4, "transited"},557{ 3, 5, "authtime"},558{ 3, 6, "starttime"},559{ 3, 7, "endtime"},560{ 3, 8, "renew-till"},561{ 3, 9, "caddr", 1003},562{ 3, 10, "authorization-data", 1004},563564{ 10, 1, "pvno"}, /* AS-REQ */565{ 10, 2, "msg-type"},566{ 10, 3, "padata", 1008},567{ 10, 4, "req-body", 1007},568569{ 11, 0, "pvno"}, /* AS-REP */570{ 11, 1, "msg-type"},571{ 11, 2, "padata", 1008},572{ 11, 3, "crealm"},573{ 11, 4, "cname", 1000},574{ 11, 5, "ticket"},575{ 11, 6, "enc-part", 1001},576577{ 12, 1, "pvno"}, /* TGS-REQ */578{ 12, 2, "msg-type"},579{ 12, 3, "padata", 1008},580{ 12, 4, "req-body", 1007},581582{ 13, 0, "pvno"}, /* TGS-REP */583{ 13, 1, "msg-type"},584{ 13, 2, "padata", 1008},585{ 13, 3, "crealm"},586{ 13, 4, "cname", 1000},587{ 13, 5, "ticket"},588{ 13, 6, "enc-part", 1001},589590{ 14, 0, "pvno"}, /* AP-REQ */591{ 14, 1, "msg-type"},592{ 14, 2, "ap-options"},593{ 14, 3, "ticket"},594{ 14, 4, "authenticator", 1001},595596{ 15, 0, "pvno"}, /* AP-REP */597{ 15, 1, "msg-type"},598{ 15, 2, "enc-part", 1001},599600{ 20, 0, "pvno"}, /* KRB-SAFE */601{ 20, 1, "msg-type"},602{ 20, 2, "safe-body", 1009},603{ 20, 3, "cksum", 1006},604605{ 21, 0, "pvno"}, /* KRB-PRIV */606{ 21, 1, "msg-type"},607{ 21, 2, "enc-part", 1001},608609{ 22, 0, "pvno"}, /* KRB-CRED */610{ 22, 1, "msg-type"},611{ 22, 2, "tickets"},612{ 22, 3, "enc-part", 1001},613614{ 25, 0, "key", 1005}, /* EncASRepPart */615{ 25, 1, "last-req", 1010},616{ 25, 2, "nonce"},617{ 25, 3, "key-expiration"},618{ 25, 4, "flags"},619{ 25, 5, "authtime"},620{ 25, 6, "starttime"},621{ 25, 7, "enddtime"},622{ 25, 8, "renew-till"},623{ 25, 9, "srealm"},624{ 25, 10, "sname", 1000},625{ 25, 11, "caddr", 1003},626627{ 26, 0, "key", 1005}, /* EncTGSRepPart */628{ 26, 1, "last-req", 1010},629{ 26, 2, "nonce"},630{ 26, 3, "key-expiration"},631{ 26, 4, "flags"},632{ 26, 5, "authtime"},633{ 26, 6, "starttime"},634{ 26, 7, "enddtime"},635{ 26, 8, "renew-till"},636{ 26, 9, "srealm"},637{ 26, 10, "sname", 1000},638{ 26, 11, "caddr", 1003},639640{ 27, 0, "ctime"}, /* EncApRepPart */641{ 27, 1, "cusec"},642{ 27, 2, "subkey", 1005},643{ 27, 3, "seq-number"},644645{ 28, 0, "user-data"}, /* EncKrbPrivPart */646{ 28, 1, "timestamp"},647{ 28, 2, "usec"},648{ 28, 3, "seq-number"},649{ 28, 4, "s-address", 1002},650{ 28, 5, "r-address", 1002},651652{ 29, 0, "ticket-info", 1011}, /* EncKrbCredPart */653{ 29, 1, "nonce"},654{ 29, 2, "timestamp"},655{ 29, 3, "usec"},656{ 29, 4, "s-address", 1002},657{ 29, 5, "r-address", 1002},658659{ 30, 0, "pvno"}, /* KRB-ERROR */660{ 30, 1, "msg-type"},661{ 30, 2, "ctime"},662{ 30, 3, "cusec"},663{ 30, 4, "stime"},664{ 30, 5, "susec"},665{ 30, 6, "error-code"},666{ 30, 7, "crealm"},667{ 30, 8, "cname", 1000},668{ 30, 9, "realm"},669{ 30, 10, "sname", 1000},670{ 30, 11, "e-text"},671{ 30, 12, "e-data"},672673{ -1, -1, 0}674};675#endif676677void678print_tag_type(FILE *fp, int eid, int lev)679{680int tag = eid & ID_TAG;681int do_space = 1;682char *str;683684fprintf(fp, "[");685686switch(eid & ID_CLASS) {687case CLASS_UNIV:688if (print_types && print_skip_tagnum)689do_space = 0;690else691fprintf(fp, "UNIV %d", tag);692break;693case CLASS_APPL:694current_appl_type = tag;695#ifdef KRB5696if (print_krb5_types) {697str = lookup_typestring(krb5_types, tag, -1);698if (str) {699fputs(str, fp);700break;701}702}703#endif704fprintf(fp, "APPL %d", tag);705break;706case CLASS_CONT:707#ifdef KRB5708if (print_krb5_types && current_appl_type) {709str = lookup_typestring(krb5_fields,710current_appl_type, tag);711if (str) {712fputs(str, fp);713break;714}715}716#endif717if (print_skip_context && lev)718fprintf(fp, "%d", tag);719else720fprintf(fp, "CONT %d", tag);721break;722case CLASS_PRIV:723fprintf(fp, "PRIV %d", tag);724break;725}726727if (print_types && ((eid & ID_CLASS) == CLASS_UNIV)) {728if (do_space)729fputs(" ", fp);730str = lookup_typestring(univ_types, eid & ID_TAG, -1);731if (str)732fputs(str, fp);733else734fprintf(fp, "UNIV %d???", eid & ID_TAG);735}736737fprintf(fp, "]");738739}740741/*****************************************************************************/742743744