1*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 2*7c478bd9Sstevel@tonic-gate /* 3*7c478bd9Sstevel@tonic-gate * src/lib/krb5/asn.1/asn1_k_decode.c 4*7c478bd9Sstevel@tonic-gate * 5*7c478bd9Sstevel@tonic-gate * Copyright 1994 by the Massachusetts Institute of Technology. 6*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 7*7c478bd9Sstevel@tonic-gate * 8*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 9*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 10*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 11*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 15*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 16*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 17*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 18*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 19*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 20*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 21*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 22*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 23*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 24*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 25*7c478bd9Sstevel@tonic-gate * or implied warranty. 26*7c478bd9Sstevel@tonic-gate */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include "asn1_k_decode.h" 29*7c478bd9Sstevel@tonic-gate #include "asn1_decode.h" 30*7c478bd9Sstevel@tonic-gate #include "asn1_get.h" 31*7c478bd9Sstevel@tonic-gate #include "asn1_misc.h" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* Declare useful decoder variables. */ 34*7c478bd9Sstevel@tonic-gate #define setup() \ 35*7c478bd9Sstevel@tonic-gate asn1_error_code retval; \ 36*7c478bd9Sstevel@tonic-gate asn1_class asn1class; \ 37*7c478bd9Sstevel@tonic-gate asn1_construction construction; \ 38*7c478bd9Sstevel@tonic-gate asn1_tagnum tagnum; \ 39*7c478bd9Sstevel@tonic-gate unsigned int length, taglen 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #define unused_var(x) if (0) { x = 0; x = x - x; } 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* This is used for prefetch of next tag in sequence. */ 44*7c478bd9Sstevel@tonic-gate #define next_tag() \ 45*7c478bd9Sstevel@tonic-gate { taginfo t2; \ 46*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(&subbuf, &t2); \ 47*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 48*7c478bd9Sstevel@tonic-gate /* Copy out to match previous functionality, until better integrated. */ \ 49*7c478bd9Sstevel@tonic-gate asn1class = t2.asn1class; \ 50*7c478bd9Sstevel@tonic-gate construction = t2.construction; \ 51*7c478bd9Sstevel@tonic-gate tagnum = t2.tagnum; \ 52*7c478bd9Sstevel@tonic-gate taglen = t2.length; \ 53*7c478bd9Sstevel@tonic-gate indef = t2.indef; \ 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* Force check for EOC tag. */ 57*7c478bd9Sstevel@tonic-gate #define get_eoc() \ 58*7c478bd9Sstevel@tonic-gate { \ 59*7c478bd9Sstevel@tonic-gate taginfo t3; \ 60*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(&subbuf, &t3); \ 61*7c478bd9Sstevel@tonic-gate if(retval) return retval; \ 62*7c478bd9Sstevel@tonic-gate if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef) \ 63*7c478bd9Sstevel@tonic-gate return ASN1_MISSING_EOC; \ 64*7c478bd9Sstevel@tonic-gate /* Copy out to match previous functionality, until better integrated. */ \ 65*7c478bd9Sstevel@tonic-gate asn1class = t3.asn1class; \ 66*7c478bd9Sstevel@tonic-gate construction = t3.construction; \ 67*7c478bd9Sstevel@tonic-gate tagnum = t3.tagnum; \ 68*7c478bd9Sstevel@tonic-gate taglen = t3.length; \ 69*7c478bd9Sstevel@tonic-gate indef = t3.indef; \ 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #define alloc_field(var, type) \ 73*7c478bd9Sstevel@tonic-gate var = (type*)calloc(1, sizeof(type)); \ 74*7c478bd9Sstevel@tonic-gate if ((var) == NULL) return ENOMEM 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #define free_field(var) \ 77*7c478bd9Sstevel@tonic-gate if ((var) != NULL) { free(var); var = NULL; } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* Fetch an expected APPLICATION class tag and verify. */ 80*7c478bd9Sstevel@tonic-gate #define apptag(tagexpect) \ 81*7c478bd9Sstevel@tonic-gate { \ 82*7c478bd9Sstevel@tonic-gate taginfo t1; \ 83*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(buf, &t1); \ 84*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 85*7c478bd9Sstevel@tonic-gate if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED || \ 86*7c478bd9Sstevel@tonic-gate t1.tagnum != (tagexpect)) return ASN1_BAD_ID; \ 87*7c478bd9Sstevel@tonic-gate /* Copy out to match previous functionality, until better integrated. */ \ 88*7c478bd9Sstevel@tonic-gate asn1class = t1.asn1class; \ 89*7c478bd9Sstevel@tonic-gate construction = t1.construction; \ 90*7c478bd9Sstevel@tonic-gate tagnum = t1.tagnum; \ 91*7c478bd9Sstevel@tonic-gate applen = t1.length; \ 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /**** normal fields ****/ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* 97*7c478bd9Sstevel@tonic-gate * get_field_body 98*7c478bd9Sstevel@tonic-gate * 99*7c478bd9Sstevel@tonic-gate * Get bare field. This also prefetches the next tag. The call to 100*7c478bd9Sstevel@tonic-gate * get_eoc() assumes that any values fetched by this macro are 101*7c478bd9Sstevel@tonic-gate * enclosed in a context-specific tag. 102*7c478bd9Sstevel@tonic-gate */ 103*7c478bd9Sstevel@tonic-gate #define get_field_body(var, decoder) \ 104*7c478bd9Sstevel@tonic-gate retval = decoder(&subbuf, &(var)); \ 105*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 106*7c478bd9Sstevel@tonic-gate if (!taglen && indef) { get_eoc(); } \ 107*7c478bd9Sstevel@tonic-gate next_tag() 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* 110*7c478bd9Sstevel@tonic-gate * get_field 111*7c478bd9Sstevel@tonic-gate * 112*7c478bd9Sstevel@tonic-gate * Get field having an expected context specific tag. This assumes 113*7c478bd9Sstevel@tonic-gate * that context-specific tags are monotonically increasing in its 114*7c478bd9Sstevel@tonic-gate * verification of tag numbers. 115*7c478bd9Sstevel@tonic-gate */ 116*7c478bd9Sstevel@tonic-gate #define get_field(var, tagexpect, decoder) \ 117*7c478bd9Sstevel@tonic-gate if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ 118*7c478bd9Sstevel@tonic-gate if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ 119*7c478bd9Sstevel@tonic-gate if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 120*7c478bd9Sstevel@tonic-gate && (tagnum || taglen || asn1class != UNIVERSAL)) \ 121*7c478bd9Sstevel@tonic-gate return ASN1_BAD_ID; \ 122*7c478bd9Sstevel@tonic-gate get_field_body(var,decoder) 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * opt_field 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * Get an optional field with an expected context specific tag. 128*7c478bd9Sstevel@tonic-gate * Assumes that OPTVAL will have the default value, thus failing to 129*7c478bd9Sstevel@tonic-gate * distinguish between absent optional values and present optional 130*7c478bd9Sstevel@tonic-gate * values that happen to have the value of OPTVAL. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate #define opt_field(var, tagexpect, decoder, optvalue) \ 133*7c478bd9Sstevel@tonic-gate if (asn1buf_remains(&subbuf, seqindef)) { \ 134*7c478bd9Sstevel@tonic-gate if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 135*7c478bd9Sstevel@tonic-gate && (tagnum || taglen || asn1class != UNIVERSAL)) \ 136*7c478bd9Sstevel@tonic-gate return ASN1_BAD_ID; \ 137*7c478bd9Sstevel@tonic-gate if (tagnum == (tagexpect)) { \ 138*7c478bd9Sstevel@tonic-gate get_field_body(var, decoder); \ 139*7c478bd9Sstevel@tonic-gate } else var = optvalue; \ 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /**** fields w/ length ****/ 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* similar to get_field_body */ 145*7c478bd9Sstevel@tonic-gate #define get_lenfield_body(len, var, decoder) \ 146*7c478bd9Sstevel@tonic-gate retval = decoder(&subbuf, &(len), &(var)); \ 147*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 148*7c478bd9Sstevel@tonic-gate if (!taglen && indef) { get_eoc(); } \ 149*7c478bd9Sstevel@tonic-gate next_tag() 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate /* similar to get_field_body */ 152*7c478bd9Sstevel@tonic-gate #define get_lenfield(len, var, tagexpect, decoder) \ 153*7c478bd9Sstevel@tonic-gate if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ 154*7c478bd9Sstevel@tonic-gate if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ 155*7c478bd9Sstevel@tonic-gate if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 156*7c478bd9Sstevel@tonic-gate && (tagnum || taglen || asn1class != UNIVERSAL)) \ 157*7c478bd9Sstevel@tonic-gate return ASN1_BAD_ID; \ 158*7c478bd9Sstevel@tonic-gate get_lenfield_body(len, var, decoder) 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* similar to opt_field */ 161*7c478bd9Sstevel@tonic-gate #define opt_lenfield(len, var, tagexpect, decoder) \ 162*7c478bd9Sstevel@tonic-gate if (tagnum == (tagexpect)) { \ 163*7c478bd9Sstevel@tonic-gate get_lenfield_body(len, var, decoder); \ 164*7c478bd9Sstevel@tonic-gate } else { len = 0; var = 0; } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * begin_structure 168*7c478bd9Sstevel@tonic-gate * 169*7c478bd9Sstevel@tonic-gate * Declares some variables for decoding SEQUENCE types. This is meant 170*7c478bd9Sstevel@tonic-gate * to be called in an inner block that ends with a call to 171*7c478bd9Sstevel@tonic-gate * end_structure(). 172*7c478bd9Sstevel@tonic-gate */ 173*7c478bd9Sstevel@tonic-gate #define begin_structure() \ 174*7c478bd9Sstevel@tonic-gate asn1buf subbuf; \ 175*7c478bd9Sstevel@tonic-gate int seqindef; \ 176*7c478bd9Sstevel@tonic-gate int indef; \ 177*7c478bd9Sstevel@tonic-gate retval = asn1_get_sequence(buf, &length, &seqindef); \ 178*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 179*7c478bd9Sstevel@tonic-gate retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \ 180*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 181*7c478bd9Sstevel@tonic-gate next_tag() 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* skip trailing garbage */ 184*7c478bd9Sstevel@tonic-gate #define end_structure() \ 185*7c478bd9Sstevel@tonic-gate retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum, \ 186*7c478bd9Sstevel@tonic-gate length, indef, seqindef); \ 187*7c478bd9Sstevel@tonic-gate if (retval) return retval 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * sequence_of 191*7c478bd9Sstevel@tonic-gate * 192*7c478bd9Sstevel@tonic-gate * Declares some variables for decoding SEQUENCE OF types. This is 193*7c478bd9Sstevel@tonic-gate * meant to be called in an inner block that ends with a call to 194*7c478bd9Sstevel@tonic-gate * end_sequence_of(). 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate #define sequence_of(buf) \ 197*7c478bd9Sstevel@tonic-gate unsigned int length, taglen; \ 198*7c478bd9Sstevel@tonic-gate asn1_class asn1class; \ 199*7c478bd9Sstevel@tonic-gate asn1_construction construction; \ 200*7c478bd9Sstevel@tonic-gate asn1_tagnum tagnum; \ 201*7c478bd9Sstevel@tonic-gate int indef; \ 202*7c478bd9Sstevel@tonic-gate sequence_of_common(buf) 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate /* 205*7c478bd9Sstevel@tonic-gate * sequence_of_no_tagvars 206*7c478bd9Sstevel@tonic-gate * 207*7c478bd9Sstevel@tonic-gate * This is meant for use inside decoder functions that have an outer 208*7c478bd9Sstevel@tonic-gate * sequence structure and thus declares variables of different names 209*7c478bd9Sstevel@tonic-gate * than does sequence_of() to avoid shadowing. 210*7c478bd9Sstevel@tonic-gate */ 211*7c478bd9Sstevel@tonic-gate #define sequence_of_no_tagvars(buf) \ 212*7c478bd9Sstevel@tonic-gate asn1_class eseqclass; \ 213*7c478bd9Sstevel@tonic-gate asn1_construction eseqconstr; \ 214*7c478bd9Sstevel@tonic-gate asn1_tagnum eseqnum; \ 215*7c478bd9Sstevel@tonic-gate unsigned int eseqlen; \ 216*7c478bd9Sstevel@tonic-gate int eseqindef; \ 217*7c478bd9Sstevel@tonic-gate sequence_of_common(buf) 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate /* 220*7c478bd9Sstevel@tonic-gate * sequence_of_common 221*7c478bd9Sstevel@tonic-gate * 222*7c478bd9Sstevel@tonic-gate * Fetches the outer SEQUENCE OF length info into {length,seqofindef} 223*7c478bd9Sstevel@tonic-gate * and imbeds an inner buffer seqbuf. Unlike begin_structure(), it 224*7c478bd9Sstevel@tonic-gate * does not prefetch the next tag. 225*7c478bd9Sstevel@tonic-gate */ 226*7c478bd9Sstevel@tonic-gate #define sequence_of_common(buf) \ 227*7c478bd9Sstevel@tonic-gate int size = 0; \ 228*7c478bd9Sstevel@tonic-gate asn1buf seqbuf; \ 229*7c478bd9Sstevel@tonic-gate int seqofindef; \ 230*7c478bd9Sstevel@tonic-gate retval = asn1_get_sequence(buf, &length, &seqofindef); \ 231*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 232*7c478bd9Sstevel@tonic-gate retval = asn1buf_imbed(&seqbuf, buf, length, seqofindef); \ 233*7c478bd9Sstevel@tonic-gate if (retval) return retval 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* 236*7c478bd9Sstevel@tonic-gate * end_sequence_of 237*7c478bd9Sstevel@tonic-gate * 238*7c478bd9Sstevel@tonic-gate * Attempts to fetch an EOC tag, if any, and to sync over trailing 239*7c478bd9Sstevel@tonic-gate * garbage, if any. 240*7c478bd9Sstevel@tonic-gate */ 241*7c478bd9Sstevel@tonic-gate #define end_sequence_of(buf) \ 242*7c478bd9Sstevel@tonic-gate { \ 243*7c478bd9Sstevel@tonic-gate taginfo t4; \ 244*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(&seqbuf, &t4); \ 245*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 246*7c478bd9Sstevel@tonic-gate /* Copy out to match previous functionality, until better integrated. */ \ 247*7c478bd9Sstevel@tonic-gate asn1class = t4.asn1class; \ 248*7c478bd9Sstevel@tonic-gate construction = t4.construction; \ 249*7c478bd9Sstevel@tonic-gate tagnum = t4.tagnum; \ 250*7c478bd9Sstevel@tonic-gate taglen = t4.length; \ 251*7c478bd9Sstevel@tonic-gate indef = t4.indef; \ 252*7c478bd9Sstevel@tonic-gate } \ 253*7c478bd9Sstevel@tonic-gate retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum, \ 254*7c478bd9Sstevel@tonic-gate length, indef, seqofindef); \ 255*7c478bd9Sstevel@tonic-gate if (retval) return retval; 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * end_sequence_of_no_tagvars 259*7c478bd9Sstevel@tonic-gate * 260*7c478bd9Sstevel@tonic-gate * Like end_sequence_of(), but uses the different (non-shadowing) 261*7c478bd9Sstevel@tonic-gate * variable names. 262*7c478bd9Sstevel@tonic-gate */ 263*7c478bd9Sstevel@tonic-gate #define end_sequence_of_no_tagvars(buf) \ 264*7c478bd9Sstevel@tonic-gate { \ 265*7c478bd9Sstevel@tonic-gate taginfo t5; \ 266*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(&seqbuf, &t5); \ 267*7c478bd9Sstevel@tonic-gate if (retval) return retval; \ 268*7c478bd9Sstevel@tonic-gate /* Copy out to match previous functionality, until better integrated. */ \ 269*7c478bd9Sstevel@tonic-gate eseqclass = t5.asn1class; \ 270*7c478bd9Sstevel@tonic-gate eseqconstr = t5.construction; \ 271*7c478bd9Sstevel@tonic-gate eseqnum = t5.tagnum; \ 272*7c478bd9Sstevel@tonic-gate eseqlen = t5.length; \ 273*7c478bd9Sstevel@tonic-gate eseqindef = t5.indef; \ 274*7c478bd9Sstevel@tonic-gate } \ 275*7c478bd9Sstevel@tonic-gate retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum, \ 276*7c478bd9Sstevel@tonic-gate eseqlen, eseqindef, seqofindef); \ 277*7c478bd9Sstevel@tonic-gate if (retval) return retval; 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate #define cleanup() \ 280*7c478bd9Sstevel@tonic-gate return 0 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate /* scalars */ 283*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_kerberos_time(asn1buf *buf, krb5_timestamp *val) 284*7c478bd9Sstevel@tonic-gate { 285*7c478bd9Sstevel@tonic-gate time_t t; 286*7c478bd9Sstevel@tonic-gate asn1_error_code retval; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate retval = asn1_decode_generaltime(buf,&t); 289*7c478bd9Sstevel@tonic-gate if (retval) 290*7c478bd9Sstevel@tonic-gate return retval; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate *val = t; 293*7c478bd9Sstevel@tonic-gate return 0; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate #define integer_convert(fname,ktype)\ 297*7c478bd9Sstevel@tonic-gate asn1_error_code fname(asn1buf * buf, ktype * val)\ 298*7c478bd9Sstevel@tonic-gate {\ 299*7c478bd9Sstevel@tonic-gate asn1_error_code retval;\ 300*7c478bd9Sstevel@tonic-gate long n;\ 301*7c478bd9Sstevel@tonic-gate retval = asn1_decode_integer(buf,&n);\ 302*7c478bd9Sstevel@tonic-gate if(retval) return retval;\ 303*7c478bd9Sstevel@tonic-gate *val = (ktype)n;\ 304*7c478bd9Sstevel@tonic-gate return 0;\ 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate #define unsigned_integer_convert(fname,ktype)\ 307*7c478bd9Sstevel@tonic-gate asn1_error_code fname(asn1buf * buf, ktype * val)\ 308*7c478bd9Sstevel@tonic-gate {\ 309*7c478bd9Sstevel@tonic-gate asn1_error_code retval;\ 310*7c478bd9Sstevel@tonic-gate unsigned long n;\ 311*7c478bd9Sstevel@tonic-gate retval = asn1_decode_unsigned_integer(buf,&n);\ 312*7c478bd9Sstevel@tonic-gate if(retval) return retval;\ 313*7c478bd9Sstevel@tonic-gate *val = (ktype)n;\ 314*7c478bd9Sstevel@tonic-gate return 0;\ 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_int,int) 317*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_int32,krb5_int32) 318*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_kvno,krb5_kvno) 319*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_enctype,krb5_enctype) 320*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_cksumtype,krb5_cksumtype) 321*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_octet,krb5_octet) 322*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_addrtype,krb5_addrtype) 323*7c478bd9Sstevel@tonic-gate integer_convert(asn1_decode_authdatatype,krb5_authdatatype) 324*7c478bd9Sstevel@tonic-gate unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2) 325*7c478bd9Sstevel@tonic-gate unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4) 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_seqnum(asn1buf *buf, krb5_ui_4 *val) 328*7c478bd9Sstevel@tonic-gate { 329*7c478bd9Sstevel@tonic-gate asn1_error_code retval; 330*7c478bd9Sstevel@tonic-gate unsigned long n; 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate retval = asn1_decode_maybe_unsigned(buf, &n); 333*7c478bd9Sstevel@tonic-gate if (retval) return retval; 334*7c478bd9Sstevel@tonic-gate *val = (krb5_ui_4)n & 0xffffffff; 335*7c478bd9Sstevel@tonic-gate return 0; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_msgtype(asn1buf *buf, krb5_msgtype *val) 339*7c478bd9Sstevel@tonic-gate { 340*7c478bd9Sstevel@tonic-gate asn1_error_code retval; 341*7c478bd9Sstevel@tonic-gate unsigned long n; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate retval = asn1_decode_unsigned_integer(buf,&n); 344*7c478bd9Sstevel@tonic-gate if(retval) return retval; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate *val = (krb5_msgtype) n; 347*7c478bd9Sstevel@tonic-gate return 0; 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /* structures */ 352*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_realm(asn1buf *buf, krb5_principal *val) 353*7c478bd9Sstevel@tonic-gate { 354*7c478bd9Sstevel@tonic-gate return asn1_decode_generalstring(buf, 355*7c478bd9Sstevel@tonic-gate (uint32_t *)&((*val)->realm.length), 356*7c478bd9Sstevel@tonic-gate &((*val)->realm.data)); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_principal_name(asn1buf *buf, krb5_principal *val) 360*7c478bd9Sstevel@tonic-gate { 361*7c478bd9Sstevel@tonic-gate setup(); 362*7c478bd9Sstevel@tonic-gate { begin_structure(); 363*7c478bd9Sstevel@tonic-gate get_field((*val)->type,0,asn1_decode_int32); 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate { sequence_of_no_tagvars(&subbuf); 366*7c478bd9Sstevel@tonic-gate while(asn1buf_remains(&seqbuf,seqofindef) > 0){ 367*7c478bd9Sstevel@tonic-gate size++; 368*7c478bd9Sstevel@tonic-gate if ((*val)->data == NULL) 369*7c478bd9Sstevel@tonic-gate (*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data)); 370*7c478bd9Sstevel@tonic-gate else 371*7c478bd9Sstevel@tonic-gate (*val)->data = (krb5_data*)realloc((*val)->data, 372*7c478bd9Sstevel@tonic-gate size*sizeof(krb5_data)); 373*7c478bd9Sstevel@tonic-gate if((*val)->data == NULL) return ENOMEM; 374*7c478bd9Sstevel@tonic-gate retval = asn1_decode_generalstring(&seqbuf, 375*7c478bd9Sstevel@tonic-gate (uint32_t *)&((*val)->data[size-1].length), 376*7c478bd9Sstevel@tonic-gate &((*val)->data[size-1].data)); 377*7c478bd9Sstevel@tonic-gate if(retval) return retval; 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate (*val)->length = size; 380*7c478bd9Sstevel@tonic-gate end_sequence_of_no_tagvars(&subbuf); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate if (indef) { 383*7c478bd9Sstevel@tonic-gate get_eoc(); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate next_tag(); 386*7c478bd9Sstevel@tonic-gate end_structure(); 387*7c478bd9Sstevel@tonic-gate (*val)->magic = KV5M_PRINCIPAL; 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate cleanup(); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_checksum(asn1buf *buf, krb5_checksum *val) 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate setup(); 395*7c478bd9Sstevel@tonic-gate { begin_structure(); 396*7c478bd9Sstevel@tonic-gate get_field(val->checksum_type,0,asn1_decode_cksumtype); 397*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 398*7c478bd9Sstevel@tonic-gate end_structure(); 399*7c478bd9Sstevel@tonic-gate val->magic = KV5M_CHECKSUM; 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate cleanup(); 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_encryption_key(asn1buf *buf, krb5_keyblock *val) 405*7c478bd9Sstevel@tonic-gate { 406*7c478bd9Sstevel@tonic-gate setup(); 407*7c478bd9Sstevel@tonic-gate { begin_structure(); 408*7c478bd9Sstevel@tonic-gate get_field(val->enctype,0,asn1_decode_enctype); 409*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 410*7c478bd9Sstevel@tonic-gate end_structure(); 411*7c478bd9Sstevel@tonic-gate val->magic = KV5M_KEYBLOCK; 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate cleanup(); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_encrypted_data(asn1buf *buf, krb5_enc_data *val) 417*7c478bd9Sstevel@tonic-gate { 418*7c478bd9Sstevel@tonic-gate setup(); 419*7c478bd9Sstevel@tonic-gate { begin_structure(); 420*7c478bd9Sstevel@tonic-gate get_field(val->enctype,0,asn1_decode_enctype); 421*7c478bd9Sstevel@tonic-gate opt_field(val->kvno,1,asn1_decode_kvno,0); 422*7c478bd9Sstevel@tonic-gate get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring); 423*7c478bd9Sstevel@tonic-gate end_structure(); 424*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ENC_DATA; 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate cleanup(); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_krb5_flags(asn1buf *buf, krb5_flags *val) 430*7c478bd9Sstevel@tonic-gate { 431*7c478bd9Sstevel@tonic-gate asn1_error_code retval; 432*7c478bd9Sstevel@tonic-gate asn1_octet unused, o; 433*7c478bd9Sstevel@tonic-gate taginfo t; 434*7c478bd9Sstevel@tonic-gate int i; 435*7c478bd9Sstevel@tonic-gate krb5_flags f=0; 436*7c478bd9Sstevel@tonic-gate unsigned int length; 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(buf, &t); 439*7c478bd9Sstevel@tonic-gate if (retval) return retval; 440*7c478bd9Sstevel@tonic-gate if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE || 441*7c478bd9Sstevel@tonic-gate t.tagnum != ASN1_BITSTRING) 442*7c478bd9Sstevel@tonic-gate return ASN1_BAD_ID; 443*7c478bd9Sstevel@tonic-gate length = t.length; 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */ 446*7c478bd9Sstevel@tonic-gate if(retval) return retval; 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate /* Number of unused bits must be between 0 and 7. */ 449*7c478bd9Sstevel@tonic-gate if (unused > 7) return ASN1_BAD_FORMAT; 450*7c478bd9Sstevel@tonic-gate length--; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate for(i = 0; i < length; i++) { 453*7c478bd9Sstevel@tonic-gate retval = asn1buf_remove_octet(buf,&o); 454*7c478bd9Sstevel@tonic-gate if(retval) return retval; 455*7c478bd9Sstevel@tonic-gate /* ignore bits past number 31 */ 456*7c478bd9Sstevel@tonic-gate if (i < 4) 457*7c478bd9Sstevel@tonic-gate f = (f<<8) | ((krb5_flags)o&0xFF); 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate if (length <= 4) { 460*7c478bd9Sstevel@tonic-gate /* Mask out unused bits, but only if necessary. */ 461*7c478bd9Sstevel@tonic-gate f &= ~(krb5_flags)0 << unused; 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate /* left-justify */ 464*7c478bd9Sstevel@tonic-gate if (length < 4) 465*7c478bd9Sstevel@tonic-gate f <<= (4 - length) * 8; 466*7c478bd9Sstevel@tonic-gate *val = f; 467*7c478bd9Sstevel@tonic-gate return 0; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate 470*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_ticket_flags(asn1buf *buf, krb5_flags *val) 471*7c478bd9Sstevel@tonic-gate { return asn1_decode_krb5_flags(buf,val); } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_ap_options(asn1buf *buf, krb5_flags *val) 474*7c478bd9Sstevel@tonic-gate { return asn1_decode_krb5_flags(buf,val); } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_kdc_options(asn1buf *buf, krb5_flags *val) 477*7c478bd9Sstevel@tonic-gate { return asn1_decode_krb5_flags(buf,val); } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_transited_encoding(asn1buf *buf, krb5_transited *val) 480*7c478bd9Sstevel@tonic-gate { 481*7c478bd9Sstevel@tonic-gate setup(); 482*7c478bd9Sstevel@tonic-gate { begin_structure(); 483*7c478bd9Sstevel@tonic-gate get_field(val->tr_type,0,asn1_decode_octet); 484*7c478bd9Sstevel@tonic-gate get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring); 485*7c478bd9Sstevel@tonic-gate end_structure(); 486*7c478bd9Sstevel@tonic-gate val->magic = KV5M_TRANSITED; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate cleanup(); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_enc_kdc_rep_part(asn1buf *buf, krb5_enc_kdc_rep_part *val) 492*7c478bd9Sstevel@tonic-gate { 493*7c478bd9Sstevel@tonic-gate setup(); 494*7c478bd9Sstevel@tonic-gate { begin_structure(); 495*7c478bd9Sstevel@tonic-gate alloc_field(val->session,krb5_keyblock); 496*7c478bd9Sstevel@tonic-gate get_field(*(val->session),0,asn1_decode_encryption_key); 497*7c478bd9Sstevel@tonic-gate get_field(val->last_req,1,asn1_decode_last_req); 498*7c478bd9Sstevel@tonic-gate get_field(val->nonce,2,asn1_decode_int32); 499*7c478bd9Sstevel@tonic-gate opt_field(val->key_exp,3,asn1_decode_kerberos_time,0); 500*7c478bd9Sstevel@tonic-gate get_field(val->flags,4,asn1_decode_ticket_flags); 501*7c478bd9Sstevel@tonic-gate get_field(val->times.authtime,5,asn1_decode_kerberos_time); 502*7c478bd9Sstevel@tonic-gate /* Set to authtime if missing */ 503*7c478bd9Sstevel@tonic-gate opt_field(val->times.starttime,6,asn1_decode_kerberos_time,val->times.authtime); 504*7c478bd9Sstevel@tonic-gate get_field(val->times.endtime,7,asn1_decode_kerberos_time); 505*7c478bd9Sstevel@tonic-gate opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0); 506*7c478bd9Sstevel@tonic-gate alloc_field(val->server,krb5_principal_data); 507*7c478bd9Sstevel@tonic-gate get_field(val->server,9,asn1_decode_realm); 508*7c478bd9Sstevel@tonic-gate get_field(val->server,10,asn1_decode_principal_name); 509*7c478bd9Sstevel@tonic-gate opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL); 510*7c478bd9Sstevel@tonic-gate end_structure(); 511*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ENC_KDC_REP_PART; 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate cleanup(); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val) 517*7c478bd9Sstevel@tonic-gate { 518*7c478bd9Sstevel@tonic-gate setup(); 519*7c478bd9Sstevel@tonic-gate unsigned int applen; 520*7c478bd9Sstevel@tonic-gate apptag(1); 521*7c478bd9Sstevel@tonic-gate { begin_structure(); 522*7c478bd9Sstevel@tonic-gate { krb5_kvno vno; 523*7c478bd9Sstevel@tonic-gate get_field(vno,0,asn1_decode_kvno); 524*7c478bd9Sstevel@tonic-gate if(vno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 525*7c478bd9Sstevel@tonic-gate alloc_field(val->server,krb5_principal_data); 526*7c478bd9Sstevel@tonic-gate get_field(val->server,1,asn1_decode_realm); 527*7c478bd9Sstevel@tonic-gate get_field(val->server,2,asn1_decode_principal_name); 528*7c478bd9Sstevel@tonic-gate get_field(val->enc_part,3,asn1_decode_encrypted_data); 529*7c478bd9Sstevel@tonic-gate end_structure(); 530*7c478bd9Sstevel@tonic-gate val->magic = KV5M_TICKET; 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate if (!applen) { 533*7c478bd9Sstevel@tonic-gate taginfo t; 534*7c478bd9Sstevel@tonic-gate retval = asn1_get_tag_2(buf, &t); 535*7c478bd9Sstevel@tonic-gate if (retval) { 536*7c478bd9Sstevel@tonic-gate free_field(val->server); 537*7c478bd9Sstevel@tonic-gate return retval; 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate cleanup(); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_kdc_req(asn1buf *buf, krb5_kdc_req *val) 544*7c478bd9Sstevel@tonic-gate { 545*7c478bd9Sstevel@tonic-gate setup(); 546*7c478bd9Sstevel@tonic-gate { begin_structure(); 547*7c478bd9Sstevel@tonic-gate { krb5_kvno kvno; 548*7c478bd9Sstevel@tonic-gate get_field(kvno,1,asn1_decode_kvno); 549*7c478bd9Sstevel@tonic-gate if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 550*7c478bd9Sstevel@tonic-gate get_field(val->msg_type,2,asn1_decode_msgtype); 551*7c478bd9Sstevel@tonic-gate opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL); 552*7c478bd9Sstevel@tonic-gate get_field(*val,4,asn1_decode_kdc_req_body); 553*7c478bd9Sstevel@tonic-gate end_structure(); 554*7c478bd9Sstevel@tonic-gate val->magic = KV5M_KDC_REQ; 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate cleanup(); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val) 560*7c478bd9Sstevel@tonic-gate { 561*7c478bd9Sstevel@tonic-gate setup(); 562*7c478bd9Sstevel@tonic-gate { 563*7c478bd9Sstevel@tonic-gate krb5_principal psave; 564*7c478bd9Sstevel@tonic-gate begin_structure(); 565*7c478bd9Sstevel@tonic-gate get_field(val->kdc_options,0,asn1_decode_kdc_options); 566*7c478bd9Sstevel@tonic-gate if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); } 567*7c478bd9Sstevel@tonic-gate opt_field(val->client,1,asn1_decode_principal_name,NULL); 568*7c478bd9Sstevel@tonic-gate alloc_field(val->server,krb5_principal_data); 569*7c478bd9Sstevel@tonic-gate get_field(val->server,2,asn1_decode_realm); 570*7c478bd9Sstevel@tonic-gate if(val->client != NULL){ 571*7c478bd9Sstevel@tonic-gate retval = asn1_krb5_realm_copy(val->client,val->server); 572*7c478bd9Sstevel@tonic-gate if(retval) { 573*7c478bd9Sstevel@tonic-gate free_field(val->server); 574*7c478bd9Sstevel@tonic-gate free_field(val->client); 575*7c478bd9Sstevel@tonic-gate return retval; } 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate /* If opt_field server is missing, memory reference to server is 580*7c478bd9Sstevel@tonic-gate lost and results in memory leak */ 581*7c478bd9Sstevel@tonic-gate psave = val->server; 582*7c478bd9Sstevel@tonic-gate opt_field(val->server,3,asn1_decode_principal_name,NULL); 583*7c478bd9Sstevel@tonic-gate if(val->server == NULL){ 584*7c478bd9Sstevel@tonic-gate if(psave->realm.data) { 585*7c478bd9Sstevel@tonic-gate free(psave->realm.data); 586*7c478bd9Sstevel@tonic-gate psave->realm.data = NULL; 587*7c478bd9Sstevel@tonic-gate psave->realm.length=0; 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate free(psave); 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate opt_field(val->from,4,asn1_decode_kerberos_time,0); 592*7c478bd9Sstevel@tonic-gate get_field(val->till,5,asn1_decode_kerberos_time); 593*7c478bd9Sstevel@tonic-gate opt_field(val->rtime,6,asn1_decode_kerberos_time,0); 594*7c478bd9Sstevel@tonic-gate get_field(val->nonce,7,asn1_decode_int32); 595*7c478bd9Sstevel@tonic-gate get_lenfield(val->nktypes,val->ktype,8,asn1_decode_sequence_of_enctype); 596*7c478bd9Sstevel@tonic-gate opt_field(val->addresses,9,asn1_decode_host_addresses,0); 597*7c478bd9Sstevel@tonic-gate if(tagnum == 10){ 598*7c478bd9Sstevel@tonic-gate get_field(val->authorization_data,10,asn1_decode_encrypted_data); } 599*7c478bd9Sstevel@tonic-gate else{ 600*7c478bd9Sstevel@tonic-gate val->authorization_data.magic = KV5M_ENC_DATA; 601*7c478bd9Sstevel@tonic-gate val->authorization_data.enctype = 0; 602*7c478bd9Sstevel@tonic-gate val->authorization_data.kvno = 0; 603*7c478bd9Sstevel@tonic-gate val->authorization_data.ciphertext.data = NULL; 604*7c478bd9Sstevel@tonic-gate val->authorization_data.ciphertext.length = 0; 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL); 607*7c478bd9Sstevel@tonic-gate end_structure(); 608*7c478bd9Sstevel@tonic-gate val->magic = KV5M_KDC_REQ; 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate cleanup(); 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_krb_safe_body(asn1buf *buf, krb5_safe *val) 614*7c478bd9Sstevel@tonic-gate { 615*7c478bd9Sstevel@tonic-gate setup(); 616*7c478bd9Sstevel@tonic-gate { begin_structure(); 617*7c478bd9Sstevel@tonic-gate get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring); 618*7c478bd9Sstevel@tonic-gate opt_field(val->timestamp,1,asn1_decode_kerberos_time,0); 619*7c478bd9Sstevel@tonic-gate opt_field(val->usec,2,asn1_decode_int32,0); 620*7c478bd9Sstevel@tonic-gate opt_field(val->seq_number,3,asn1_decode_seqnum,0); 621*7c478bd9Sstevel@tonic-gate alloc_field(val->s_address,krb5_address); 622*7c478bd9Sstevel@tonic-gate get_field(*(val->s_address),4,asn1_decode_host_address); 623*7c478bd9Sstevel@tonic-gate if(tagnum == 5){ 624*7c478bd9Sstevel@tonic-gate alloc_field(val->r_address,krb5_address); 625*7c478bd9Sstevel@tonic-gate get_field(*(val->r_address),5,asn1_decode_host_address); 626*7c478bd9Sstevel@tonic-gate } else val->r_address = NULL; 627*7c478bd9Sstevel@tonic-gate end_structure(); 628*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAFE; 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate cleanup(); 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_host_address(asn1buf *buf, krb5_address *val) 634*7c478bd9Sstevel@tonic-gate { 635*7c478bd9Sstevel@tonic-gate setup(); 636*7c478bd9Sstevel@tonic-gate { begin_structure(); 637*7c478bd9Sstevel@tonic-gate get_field(val->addrtype,0,asn1_decode_addrtype); 638*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 639*7c478bd9Sstevel@tonic-gate end_structure(); 640*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ADDRESS; 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate cleanup(); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_kdc_rep(asn1buf *buf, krb5_kdc_rep *val) 646*7c478bd9Sstevel@tonic-gate { 647*7c478bd9Sstevel@tonic-gate setup(); 648*7c478bd9Sstevel@tonic-gate { begin_structure(); 649*7c478bd9Sstevel@tonic-gate { krb5_kvno pvno; 650*7c478bd9Sstevel@tonic-gate get_field(pvno,0,asn1_decode_kvno); 651*7c478bd9Sstevel@tonic-gate if(pvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 652*7c478bd9Sstevel@tonic-gate get_field(val->msg_type,1,asn1_decode_msgtype); 653*7c478bd9Sstevel@tonic-gate opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL); 654*7c478bd9Sstevel@tonic-gate alloc_field(val->client,krb5_principal_data); 655*7c478bd9Sstevel@tonic-gate get_field(val->client,3,asn1_decode_realm); 656*7c478bd9Sstevel@tonic-gate get_field(val->client,4,asn1_decode_principal_name); 657*7c478bd9Sstevel@tonic-gate alloc_field(val->ticket,krb5_ticket); 658*7c478bd9Sstevel@tonic-gate get_field(*(val->ticket),5,asn1_decode_ticket); 659*7c478bd9Sstevel@tonic-gate get_field(val->enc_part,6,asn1_decode_encrypted_data); 660*7c478bd9Sstevel@tonic-gate end_structure(); 661*7c478bd9Sstevel@tonic-gate val->magic = KV5M_KDC_REP; 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate cleanup(); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate /* arrays */ 668*7c478bd9Sstevel@tonic-gate #define get_element(element,decoder)\ 669*7c478bd9Sstevel@tonic-gate retval = decoder(&seqbuf,element);\ 670*7c478bd9Sstevel@tonic-gate if(retval) return retval 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate #define array_append(array,size,element,type)\ 673*7c478bd9Sstevel@tonic-gate size++;\ 674*7c478bd9Sstevel@tonic-gate if (*(array) == NULL)\ 675*7c478bd9Sstevel@tonic-gate *(array) = (type**)malloc((size+1)*sizeof(type*));\ 676*7c478bd9Sstevel@tonic-gate else\ 677*7c478bd9Sstevel@tonic-gate *(array) = (type**)realloc(*(array),\ 678*7c478bd9Sstevel@tonic-gate (size+1)*sizeof(type*));\ 679*7c478bd9Sstevel@tonic-gate if(*(array) == NULL) return ENOMEM;\ 680*7c478bd9Sstevel@tonic-gate (*(array))[(size)-1] = elt 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate #define decode_array_body(type,decoder)\ 683*7c478bd9Sstevel@tonic-gate asn1_error_code retval;\ 684*7c478bd9Sstevel@tonic-gate type *elt;\ 685*7c478bd9Sstevel@tonic-gate \ 686*7c478bd9Sstevel@tonic-gate { sequence_of(buf);\ 687*7c478bd9Sstevel@tonic-gate while(asn1buf_remains(&seqbuf,seqofindef) > 0){\ 688*7c478bd9Sstevel@tonic-gate alloc_field(elt,type);\ 689*7c478bd9Sstevel@tonic-gate get_element(elt,decoder);\ 690*7c478bd9Sstevel@tonic-gate array_append(val,size,elt,type);\ 691*7c478bd9Sstevel@tonic-gate }\ 692*7c478bd9Sstevel@tonic-gate if (*val == NULL)\ 693*7c478bd9Sstevel@tonic-gate *val = (type **)malloc(sizeof(type*));\ 694*7c478bd9Sstevel@tonic-gate (*val)[size] = NULL;\ 695*7c478bd9Sstevel@tonic-gate end_sequence_of(buf);\ 696*7c478bd9Sstevel@tonic-gate }\ 697*7c478bd9Sstevel@tonic-gate cleanup() 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_authorization_data(asn1buf *buf, krb5_authdata ***val) 701*7c478bd9Sstevel@tonic-gate { 702*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_authdata,asn1_decode_authdata_elt); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_authdata_elt(asn1buf *buf, krb5_authdata *val) 706*7c478bd9Sstevel@tonic-gate { 707*7c478bd9Sstevel@tonic-gate setup(); 708*7c478bd9Sstevel@tonic-gate { begin_structure(); 709*7c478bd9Sstevel@tonic-gate get_field(val->ad_type,0,asn1_decode_authdatatype); 710*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 711*7c478bd9Sstevel@tonic-gate end_structure(); 712*7c478bd9Sstevel@tonic-gate val->magic = KV5M_AUTHDATA; 713*7c478bd9Sstevel@tonic-gate } 714*7c478bd9Sstevel@tonic-gate cleanup(); 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_host_addresses(asn1buf *buf, krb5_address ***val) 718*7c478bd9Sstevel@tonic-gate { 719*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_address,asn1_decode_host_address); 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_ticket(asn1buf *buf, krb5_ticket ***val) 723*7c478bd9Sstevel@tonic-gate { 724*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_ticket,asn1_decode_ticket); 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_krb_cred_info(asn1buf *buf, krb5_cred_info ***val) 728*7c478bd9Sstevel@tonic-gate { 729*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info); 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_krb_cred_info(asn1buf *buf, krb5_cred_info *val) 733*7c478bd9Sstevel@tonic-gate { 734*7c478bd9Sstevel@tonic-gate setup(); 735*7c478bd9Sstevel@tonic-gate { begin_structure(); 736*7c478bd9Sstevel@tonic-gate alloc_field(val->session,krb5_keyblock); 737*7c478bd9Sstevel@tonic-gate get_field(*(val->session),0,asn1_decode_encryption_key); 738*7c478bd9Sstevel@tonic-gate if(tagnum == 1){ 739*7c478bd9Sstevel@tonic-gate alloc_field(val->client,krb5_principal_data); 740*7c478bd9Sstevel@tonic-gate opt_field(val->client,1,asn1_decode_realm,NULL); 741*7c478bd9Sstevel@tonic-gate opt_field(val->client,2,asn1_decode_principal_name,NULL); } 742*7c478bd9Sstevel@tonic-gate opt_field(val->flags,3,asn1_decode_ticket_flags,0); 743*7c478bd9Sstevel@tonic-gate opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0); 744*7c478bd9Sstevel@tonic-gate opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0); 745*7c478bd9Sstevel@tonic-gate opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0); 746*7c478bd9Sstevel@tonic-gate opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0); 747*7c478bd9Sstevel@tonic-gate if(tagnum == 8){ 748*7c478bd9Sstevel@tonic-gate alloc_field(val->server,krb5_principal_data); 749*7c478bd9Sstevel@tonic-gate opt_field(val->server,8,asn1_decode_realm,NULL); 750*7c478bd9Sstevel@tonic-gate opt_field(val->server,9,asn1_decode_principal_name,NULL); } 751*7c478bd9Sstevel@tonic-gate opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL); 752*7c478bd9Sstevel@tonic-gate end_structure(); 753*7c478bd9Sstevel@tonic-gate val->magic = KV5M_CRED_INFO; 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate cleanup(); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_pa_data(asn1buf *buf, krb5_pa_data ***val) 759*7c478bd9Sstevel@tonic-gate { 760*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_pa_data,asn1_decode_pa_data); 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_pa_data(asn1buf *buf, krb5_pa_data *val) 764*7c478bd9Sstevel@tonic-gate { 765*7c478bd9Sstevel@tonic-gate setup(); 766*7c478bd9Sstevel@tonic-gate { begin_structure(); 767*7c478bd9Sstevel@tonic-gate get_field(val->pa_type,1,asn1_decode_int32); 768*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->contents,2,asn1_decode_octetstring); 769*7c478bd9Sstevel@tonic-gate end_structure(); 770*7c478bd9Sstevel@tonic-gate val->magic = KV5M_PA_DATA; 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate cleanup(); 773*7c478bd9Sstevel@tonic-gate } 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_last_req(asn1buf *buf, krb5_last_req_entry ***val) 776*7c478bd9Sstevel@tonic-gate { 777*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry); 778*7c478bd9Sstevel@tonic-gate } 779*7c478bd9Sstevel@tonic-gate 780*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_last_req_entry(asn1buf *buf, krb5_last_req_entry *val) 781*7c478bd9Sstevel@tonic-gate { 782*7c478bd9Sstevel@tonic-gate setup(); 783*7c478bd9Sstevel@tonic-gate { begin_structure(); 784*7c478bd9Sstevel@tonic-gate get_field(val->lr_type,0,asn1_decode_int32); 785*7c478bd9Sstevel@tonic-gate get_field(val->value,1,asn1_decode_kerberos_time); 786*7c478bd9Sstevel@tonic-gate end_structure(); 787*7c478bd9Sstevel@tonic-gate val->magic = KV5M_LAST_REQ_ENTRY; 788*7c478bd9Sstevel@tonic-gate #ifdef KRB5_GENEROUS_LR_TYPE 789*7c478bd9Sstevel@tonic-gate /* If we are only a single byte wide and negative - fill in the 790*7c478bd9Sstevel@tonic-gate other bits */ 791*7c478bd9Sstevel@tonic-gate if((val->lr_type & 0xffffff80U) == 0x80) val->lr_type |= 0xffffff00U; 792*7c478bd9Sstevel@tonic-gate #endif 793*7c478bd9Sstevel@tonic-gate } 794*7c478bd9Sstevel@tonic-gate cleanup(); 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_enctype(asn1buf *buf, int *num, krb5_enctype **val) 798*7c478bd9Sstevel@tonic-gate { 799*7c478bd9Sstevel@tonic-gate asn1_error_code retval; 800*7c478bd9Sstevel@tonic-gate { sequence_of(buf); 801*7c478bd9Sstevel@tonic-gate while(asn1buf_remains(&seqbuf,seqofindef) > 0){ 802*7c478bd9Sstevel@tonic-gate size++; 803*7c478bd9Sstevel@tonic-gate if (*val == NULL) 804*7c478bd9Sstevel@tonic-gate *val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype)); 805*7c478bd9Sstevel@tonic-gate else 806*7c478bd9Sstevel@tonic-gate *val = (krb5_enctype*)realloc(*val,size*sizeof(krb5_enctype)); 807*7c478bd9Sstevel@tonic-gate if(*val == NULL) return ENOMEM; 808*7c478bd9Sstevel@tonic-gate retval = asn1_decode_enctype(&seqbuf,&((*val)[size-1])); 809*7c478bd9Sstevel@tonic-gate if(retval) return retval; 810*7c478bd9Sstevel@tonic-gate } 811*7c478bd9Sstevel@tonic-gate *num = size; 812*7c478bd9Sstevel@tonic-gate end_sequence_of(buf); 813*7c478bd9Sstevel@tonic-gate } 814*7c478bd9Sstevel@tonic-gate cleanup(); 815*7c478bd9Sstevel@tonic-gate } 816*7c478bd9Sstevel@tonic-gate 817*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_checksum(asn1buf *buf, krb5_checksum ***val) 818*7c478bd9Sstevel@tonic-gate { 819*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_checksum, asn1_decode_checksum); 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate static asn1_error_code asn1_decode_etype_info2_entry(asn1buf *buf, krb5_etype_info_entry *val ) 823*7c478bd9Sstevel@tonic-gate { 824*7c478bd9Sstevel@tonic-gate setup(); 825*7c478bd9Sstevel@tonic-gate { begin_structure(); 826*7c478bd9Sstevel@tonic-gate get_field(val->etype,0,asn1_decode_enctype); 827*7c478bd9Sstevel@tonic-gate if (tagnum == 1) { 828*7c478bd9Sstevel@tonic-gate char *s = (char *)val->salt; 829*7c478bd9Sstevel@tonic-gate get_lenfield(val->length, s, 1, asn1_decode_generalstring); 830*7c478bd9Sstevel@tonic-gate } else { 831*7c478bd9Sstevel@tonic-gate val->length = KRB5_ETYPE_NO_SALT; 832*7c478bd9Sstevel@tonic-gate val->salt = 0; 833*7c478bd9Sstevel@tonic-gate } 834*7c478bd9Sstevel@tonic-gate if ( tagnum ==2) { 835*7c478bd9Sstevel@tonic-gate krb5_octet *params ; 836*7c478bd9Sstevel@tonic-gate get_lenfield( val->s2kparams.length, params, 837*7c478bd9Sstevel@tonic-gate 2, asn1_decode_octetstring); 838*7c478bd9Sstevel@tonic-gate val->s2kparams.data = ( char *) params; 839*7c478bd9Sstevel@tonic-gate } else { 840*7c478bd9Sstevel@tonic-gate val->s2kparams.data = NULL; 841*7c478bd9Sstevel@tonic-gate val->s2kparams.length = 0; 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate end_structure(); 844*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ETYPE_INFO_ENTRY; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate cleanup(); 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate 849*7c478bd9Sstevel@tonic-gate static asn1_error_code asn1_decode_etype_info2_entry_1_3(asn1buf *buf, krb5_etype_info_entry *val ) 850*7c478bd9Sstevel@tonic-gate { 851*7c478bd9Sstevel@tonic-gate setup(); 852*7c478bd9Sstevel@tonic-gate { begin_structure(); 853*7c478bd9Sstevel@tonic-gate get_field(val->etype,0,asn1_decode_enctype); 854*7c478bd9Sstevel@tonic-gate if (tagnum == 1) { 855*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->salt,1,asn1_decode_octetstring); 856*7c478bd9Sstevel@tonic-gate } else { 857*7c478bd9Sstevel@tonic-gate val->length = KRB5_ETYPE_NO_SALT; 858*7c478bd9Sstevel@tonic-gate val->salt = 0; 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate if ( tagnum ==2) { 861*7c478bd9Sstevel@tonic-gate krb5_octet *params ; 862*7c478bd9Sstevel@tonic-gate get_lenfield( val->s2kparams.length, params, 863*7c478bd9Sstevel@tonic-gate 2, asn1_decode_octetstring); 864*7c478bd9Sstevel@tonic-gate val->s2kparams.data = ( char *) params; 865*7c478bd9Sstevel@tonic-gate } else { 866*7c478bd9Sstevel@tonic-gate val->s2kparams.data = NULL; 867*7c478bd9Sstevel@tonic-gate val->s2kparams.length = 0; 868*7c478bd9Sstevel@tonic-gate } 869*7c478bd9Sstevel@tonic-gate end_structure(); 870*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ETYPE_INFO_ENTRY; 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate cleanup(); 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val ) 876*7c478bd9Sstevel@tonic-gate { 877*7c478bd9Sstevel@tonic-gate setup(); 878*7c478bd9Sstevel@tonic-gate { begin_structure(); 879*7c478bd9Sstevel@tonic-gate get_field(val->etype,0,asn1_decode_enctype); 880*7c478bd9Sstevel@tonic-gate if (tagnum == 1) { 881*7c478bd9Sstevel@tonic-gate get_lenfield(val->length,val->salt,1,asn1_decode_octetstring); 882*7c478bd9Sstevel@tonic-gate } else { 883*7c478bd9Sstevel@tonic-gate val->length = KRB5_ETYPE_NO_SALT; 884*7c478bd9Sstevel@tonic-gate val->salt = 0; 885*7c478bd9Sstevel@tonic-gate } 886*7c478bd9Sstevel@tonic-gate val->s2kparams.data = NULL; 887*7c478bd9Sstevel@tonic-gate val->s2kparams.length = 0; 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate end_structure(); 890*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ETYPE_INFO_ENTRY; 891*7c478bd9Sstevel@tonic-gate } 892*7c478bd9Sstevel@tonic-gate cleanup(); 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate 895*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val ) 896*7c478bd9Sstevel@tonic-gate { 897*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate 900*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_etype_info2(asn1buf *buf, krb5_etype_info_entry ***val , 901*7c478bd9Sstevel@tonic-gate krb5_boolean v1_3_behavior) 902*7c478bd9Sstevel@tonic-gate { 903*7c478bd9Sstevel@tonic-gate if (v1_3_behavior) { 904*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_etype_info_entry, 905*7c478bd9Sstevel@tonic-gate asn1_decode_etype_info2_entry_1_3); 906*7c478bd9Sstevel@tonic-gate } else { 907*7c478bd9Sstevel@tonic-gate decode_array_body(krb5_etype_info_entry, 908*7c478bd9Sstevel@tonic-gate asn1_decode_etype_info2_entry); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_passwdsequence(asn1buf *buf, passwd_phrase_element *val) 913*7c478bd9Sstevel@tonic-gate { 914*7c478bd9Sstevel@tonic-gate setup(); 915*7c478bd9Sstevel@tonic-gate { begin_structure(); 916*7c478bd9Sstevel@tonic-gate alloc_field(val->passwd,krb5_data); 917*7c478bd9Sstevel@tonic-gate get_lenfield(val->passwd->length,val->passwd->data, 918*7c478bd9Sstevel@tonic-gate 0,asn1_decode_charstring); 919*7c478bd9Sstevel@tonic-gate val->passwd->magic = KV5M_DATA; 920*7c478bd9Sstevel@tonic-gate alloc_field(val->phrase,krb5_data); 921*7c478bd9Sstevel@tonic-gate get_lenfield(val->phrase->length,val->phrase->data, 922*7c478bd9Sstevel@tonic-gate 1,asn1_decode_charstring); 923*7c478bd9Sstevel@tonic-gate val->phrase->magic = KV5M_DATA; 924*7c478bd9Sstevel@tonic-gate end_structure(); 925*7c478bd9Sstevel@tonic-gate val->magic = KV5M_PASSWD_PHRASE_ELEMENT; 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate cleanup(); 928*7c478bd9Sstevel@tonic-gate } 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sequence_of_passwdsequence(asn1buf *buf, passwd_phrase_element ***val) 931*7c478bd9Sstevel@tonic-gate { 932*7c478bd9Sstevel@tonic-gate decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence); 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_flags(asn1buf *buf, krb5_flags *val) 936*7c478bd9Sstevel@tonic-gate { return asn1_decode_krb5_flags(buf,val); } 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate #define opt_string(val,n,fn) opt_lenfield((val).length,(val).data,n,fn) 939*7c478bd9Sstevel@tonic-gate #define opt_cksum(var,tagexpect,decoder)\ 940*7c478bd9Sstevel@tonic-gate if(tagnum == (tagexpect)){\ 941*7c478bd9Sstevel@tonic-gate get_field_body(var,decoder); }\ 942*7c478bd9Sstevel@tonic-gate else var.length = 0 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_challenge(asn1buf *buf, krb5_sam_challenge *val) 945*7c478bd9Sstevel@tonic-gate { 946*7c478bd9Sstevel@tonic-gate setup(); 947*7c478bd9Sstevel@tonic-gate { begin_structure(); 948*7c478bd9Sstevel@tonic-gate get_field(val->sam_type,0,asn1_decode_int32); 949*7c478bd9Sstevel@tonic-gate get_field(val->sam_flags,1,asn1_decode_sam_flags); 950*7c478bd9Sstevel@tonic-gate opt_string(val->sam_type_name,2,asn1_decode_charstring); 951*7c478bd9Sstevel@tonic-gate opt_string(val->sam_track_id,3,asn1_decode_charstring); 952*7c478bd9Sstevel@tonic-gate opt_string(val->sam_challenge_label,4,asn1_decode_charstring); 953*7c478bd9Sstevel@tonic-gate opt_string(val->sam_challenge,5,asn1_decode_charstring); 954*7c478bd9Sstevel@tonic-gate opt_string(val->sam_response_prompt,6,asn1_decode_charstring); 955*7c478bd9Sstevel@tonic-gate opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring); 956*7c478bd9Sstevel@tonic-gate opt_field(val->sam_nonce,8,asn1_decode_int32,0); 957*7c478bd9Sstevel@tonic-gate opt_cksum(val->sam_cksum,9,asn1_decode_checksum); 958*7c478bd9Sstevel@tonic-gate end_structure(); 959*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAM_CHALLENGE; 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate cleanup(); 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_challenge_2(asn1buf *buf, krb5_sam_challenge_2 *val) 964*7c478bd9Sstevel@tonic-gate { 965*7c478bd9Sstevel@tonic-gate setup(); 966*7c478bd9Sstevel@tonic-gate { char *save, *end; 967*7c478bd9Sstevel@tonic-gate size_t alloclen; 968*7c478bd9Sstevel@tonic-gate begin_structure(); 969*7c478bd9Sstevel@tonic-gate if (tagnum != 0) return ASN1_MISSING_FIELD; 970*7c478bd9Sstevel@tonic-gate if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 971*7c478bd9Sstevel@tonic-gate return ASN1_BAD_ID; 972*7c478bd9Sstevel@tonic-gate save = subbuf.next; 973*7c478bd9Sstevel@tonic-gate { sequence_of_no_tagvars(&subbuf); 974*7c478bd9Sstevel@tonic-gate unused_var(size); 975*7c478bd9Sstevel@tonic-gate end_sequence_of_no_tagvars(&subbuf); 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate end = subbuf.next; 978*7c478bd9Sstevel@tonic-gate alloclen = end - save; 979*7c478bd9Sstevel@tonic-gate if ((val->sam_challenge_2_body.data = (char *) malloc(alloclen)) == NULL) 980*7c478bd9Sstevel@tonic-gate return ENOMEM; 981*7c478bd9Sstevel@tonic-gate val->sam_challenge_2_body.length = alloclen; 982*7c478bd9Sstevel@tonic-gate memcpy(val->sam_challenge_2_body.data, save, alloclen); 983*7c478bd9Sstevel@tonic-gate next_tag(); 984*7c478bd9Sstevel@tonic-gate get_field(val->sam_cksum, 1, asn1_decode_sequence_of_checksum); 985*7c478bd9Sstevel@tonic-gate end_structure(); 986*7c478bd9Sstevel@tonic-gate } 987*7c478bd9Sstevel@tonic-gate cleanup(); 988*7c478bd9Sstevel@tonic-gate } 989*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_challenge_2_body(asn1buf *buf, krb5_sam_challenge_2_body *val) 990*7c478bd9Sstevel@tonic-gate { 991*7c478bd9Sstevel@tonic-gate setup(); 992*7c478bd9Sstevel@tonic-gate { begin_structure(); 993*7c478bd9Sstevel@tonic-gate get_field(val->sam_type,0,asn1_decode_int32); 994*7c478bd9Sstevel@tonic-gate get_field(val->sam_flags,1,asn1_decode_sam_flags); 995*7c478bd9Sstevel@tonic-gate opt_string(val->sam_type_name,2,asn1_decode_charstring); 996*7c478bd9Sstevel@tonic-gate opt_string(val->sam_track_id,3,asn1_decode_charstring); 997*7c478bd9Sstevel@tonic-gate opt_string(val->sam_challenge_label,4,asn1_decode_charstring); 998*7c478bd9Sstevel@tonic-gate opt_string(val->sam_challenge,5,asn1_decode_charstring); 999*7c478bd9Sstevel@tonic-gate opt_string(val->sam_response_prompt,6,asn1_decode_charstring); 1000*7c478bd9Sstevel@tonic-gate opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring); 1001*7c478bd9Sstevel@tonic-gate get_field(val->sam_nonce,8,asn1_decode_int32); 1002*7c478bd9Sstevel@tonic-gate get_field(val->sam_etype, 9, asn1_decode_int32); 1003*7c478bd9Sstevel@tonic-gate end_structure(); 1004*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAM_CHALLENGE; 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate cleanup(); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_enc_sam_key(asn1buf *buf, krb5_sam_key *val) 1009*7c478bd9Sstevel@tonic-gate { 1010*7c478bd9Sstevel@tonic-gate setup(); 1011*7c478bd9Sstevel@tonic-gate { begin_structure(); 1012*7c478bd9Sstevel@tonic-gate /* alloc_field(val->sam_key,krb5_keyblock); */ 1013*7c478bd9Sstevel@tonic-gate get_field(val->sam_key,0,asn1_decode_encryption_key); 1014*7c478bd9Sstevel@tonic-gate end_structure(); 1015*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAM_KEY; 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate cleanup(); 1018*7c478bd9Sstevel@tonic-gate } 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_enc_sam_response_enc(asn1buf *buf, krb5_enc_sam_response_enc *val) 1021*7c478bd9Sstevel@tonic-gate { 1022*7c478bd9Sstevel@tonic-gate setup(); 1023*7c478bd9Sstevel@tonic-gate { begin_structure(); 1024*7c478bd9Sstevel@tonic-gate opt_field(val->sam_nonce,0,asn1_decode_int32,0); 1025*7c478bd9Sstevel@tonic-gate opt_field(val->sam_timestamp,1,asn1_decode_kerberos_time,0); 1026*7c478bd9Sstevel@tonic-gate opt_field(val->sam_usec,2,asn1_decode_int32,0); 1027*7c478bd9Sstevel@tonic-gate opt_string(val->sam_sad,3,asn1_decode_charstring); 1028*7c478bd9Sstevel@tonic-gate end_structure(); 1029*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ENC_SAM_RESPONSE_ENC; 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate cleanup(); 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate 1034*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_enc_sam_response_enc_2(asn1buf *buf, krb5_enc_sam_response_enc_2 *val) 1035*7c478bd9Sstevel@tonic-gate { 1036*7c478bd9Sstevel@tonic-gate setup(); 1037*7c478bd9Sstevel@tonic-gate { begin_structure(); 1038*7c478bd9Sstevel@tonic-gate get_field(val->sam_nonce,0,asn1_decode_int32); 1039*7c478bd9Sstevel@tonic-gate opt_string(val->sam_sad,1,asn1_decode_charstring); 1040*7c478bd9Sstevel@tonic-gate end_structure(); 1041*7c478bd9Sstevel@tonic-gate val->magic = KV5M_ENC_SAM_RESPONSE_ENC_2; 1042*7c478bd9Sstevel@tonic-gate } 1043*7c478bd9Sstevel@tonic-gate cleanup(); 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate #define opt_encfield(fld,tag,fn) \ 1047*7c478bd9Sstevel@tonic-gate if(tagnum == tag){ \ 1048*7c478bd9Sstevel@tonic-gate get_field(fld,tag,fn); } \ 1049*7c478bd9Sstevel@tonic-gate else{\ 1050*7c478bd9Sstevel@tonic-gate fld.magic = 0;\ 1051*7c478bd9Sstevel@tonic-gate fld.enctype = 0;\ 1052*7c478bd9Sstevel@tonic-gate fld.kvno = 0;\ 1053*7c478bd9Sstevel@tonic-gate fld.ciphertext.data = NULL;\ 1054*7c478bd9Sstevel@tonic-gate fld.ciphertext.length = 0;\ 1055*7c478bd9Sstevel@tonic-gate } 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_response(asn1buf *buf, krb5_sam_response *val) 1058*7c478bd9Sstevel@tonic-gate { 1059*7c478bd9Sstevel@tonic-gate setup(); 1060*7c478bd9Sstevel@tonic-gate { begin_structure(); 1061*7c478bd9Sstevel@tonic-gate get_field(val->sam_type,0,asn1_decode_int32); 1062*7c478bd9Sstevel@tonic-gate get_field(val->sam_flags,1,asn1_decode_sam_flags); 1063*7c478bd9Sstevel@tonic-gate opt_string(val->sam_track_id,2,asn1_decode_charstring); 1064*7c478bd9Sstevel@tonic-gate opt_encfield(val->sam_enc_key,3,asn1_decode_encrypted_data); 1065*7c478bd9Sstevel@tonic-gate get_field(val->sam_enc_nonce_or_ts,4,asn1_decode_encrypted_data); 1066*7c478bd9Sstevel@tonic-gate opt_field(val->sam_nonce,5,asn1_decode_int32,0); 1067*7c478bd9Sstevel@tonic-gate opt_field(val->sam_patimestamp,6,asn1_decode_kerberos_time,0); 1068*7c478bd9Sstevel@tonic-gate end_structure(); 1069*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAM_RESPONSE; 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate cleanup(); 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_sam_response_2(asn1buf *buf, krb5_sam_response_2 *val) 1075*7c478bd9Sstevel@tonic-gate { 1076*7c478bd9Sstevel@tonic-gate setup(); 1077*7c478bd9Sstevel@tonic-gate { begin_structure(); 1078*7c478bd9Sstevel@tonic-gate get_field(val->sam_type,0,asn1_decode_int32); 1079*7c478bd9Sstevel@tonic-gate get_field(val->sam_flags,1,asn1_decode_sam_flags); 1080*7c478bd9Sstevel@tonic-gate opt_string(val->sam_track_id,2,asn1_decode_charstring); 1081*7c478bd9Sstevel@tonic-gate get_field(val->sam_enc_nonce_or_sad,3,asn1_decode_encrypted_data); 1082*7c478bd9Sstevel@tonic-gate get_field(val->sam_nonce,4,asn1_decode_int32); 1083*7c478bd9Sstevel@tonic-gate end_structure(); 1084*7c478bd9Sstevel@tonic-gate val->magic = KV5M_SAM_RESPONSE; 1085*7c478bd9Sstevel@tonic-gate } 1086*7c478bd9Sstevel@tonic-gate cleanup(); 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate asn1_error_code asn1_decode_predicted_sam_response(asn1buf *buf, krb5_predicted_sam_response *val) 1091*7c478bd9Sstevel@tonic-gate { 1092*7c478bd9Sstevel@tonic-gate setup(); 1093*7c478bd9Sstevel@tonic-gate { begin_structure(); 1094*7c478bd9Sstevel@tonic-gate get_field(val->sam_key,0,asn1_decode_encryption_key); 1095*7c478bd9Sstevel@tonic-gate get_field(val->sam_flags,1,asn1_decode_sam_flags); 1096*7c478bd9Sstevel@tonic-gate get_field(val->stime,2,asn1_decode_kerberos_time); 1097*7c478bd9Sstevel@tonic-gate get_field(val->susec,3,asn1_decode_int32); 1098*7c478bd9Sstevel@tonic-gate alloc_field(val->client,krb5_principal_data); 1099*7c478bd9Sstevel@tonic-gate get_field(val->client,4,asn1_decode_realm); 1100*7c478bd9Sstevel@tonic-gate get_field(val->client,5,asn1_decode_principal_name); 1101*7c478bd9Sstevel@tonic-gate opt_string(val->msd,6,asn1_decode_charstring); /* should be octet */ 1102*7c478bd9Sstevel@tonic-gate end_structure(); 1103*7c478bd9Sstevel@tonic-gate val->magic = KV5M_PREDICTED_SAM_RESPONSE; 1104*7c478bd9Sstevel@tonic-gate } 1105*7c478bd9Sstevel@tonic-gate cleanup(); 1106*7c478bd9Sstevel@tonic-gate } 1107