1 #pragma ident "%Z%%M% %I% %E% SMI" 2 3 /* 4 * src/lib/krb5/asn.1/asn1_get.c 5 * 6 * Copyright 1994 by the Massachusetts Institute of Technology. 7 * All Rights Reserved. 8 * 9 * Export of this software from the United States of America may 10 * require a specific license from the United States Government. 11 * It is the responsibility of any person or organization contemplating 12 * export to obtain such a license before exporting. 13 * 14 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 15 * distribute this software and its documentation for any purpose and 16 * without fee is hereby granted, provided that the above copyright 17 * notice appear in all copies and that both that copyright notice and 18 * this permission notice appear in supporting documentation, and that 19 * the name of M.I.T. not be used in advertising or publicity pertaining 20 * to distribution of the software without specific, written prior 21 * permission. Furthermore if you modify this software you must label 22 * your software as modified software and not distribute it in such a 23 * fashion that it might be confused with the original M.I.T. software. 24 * M.I.T. makes no representations about the suitability of 25 * this software for any purpose. It is provided "as is" without express 26 * or implied warranty. 27 */ 28 29 #include "asn1_get.h" 30 31 asn1_error_code 32 asn1_get_tag_2(asn1buf *buf, taginfo *t) 33 { 34 asn1_error_code retval; 35 36 if (buf == NULL || buf->base == NULL || 37 buf->bound - buf->next + 1 <= 0) { 38 t->tagnum = ASN1_TAGNUM_CEILING; /* emphatically not an EOC tag */ 39 t->asn1class = UNIVERSAL; 40 t->construction = PRIMITIVE; 41 t->length = 0; 42 t->indef = 0; 43 return 0; 44 } 45 { 46 /* asn1_get_id(buf, t) */ 47 asn1_tagnum tn=0; 48 asn1_octet o; 49 50 #define ASN1_CLASS_MASK 0xC0 51 #define ASN1_CONSTRUCTION_MASK 0x20 52 #define ASN1_TAG_NUMBER_MASK 0x1F 53 54 retval = asn1buf_remove_octet(buf,&o); 55 if (retval) 56 return retval; 57 58 t->asn1class = (asn1_class)(o&ASN1_CLASS_MASK); 59 t->construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK); 60 if ((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){ 61 /* low-tag-number form */ 62 t->tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK); 63 } else { 64 /* high-tag-number form */ 65 do { 66 retval = asn1buf_remove_octet(buf,&o); 67 if (retval) return retval; 68 tn = (tn<<7) + (asn1_tagnum)(o&0x7F); 69 }while(tn&0x80); 70 t->tagnum = tn; 71 } 72 } 73 74 { 75 /* asn1_get_length(buf, t) */ 76 asn1_octet o; 77 78 t->indef = 0; 79 retval = asn1buf_remove_octet(buf,&o); 80 if (retval) return retval; 81 if ((o&0x80) == 0) { 82 t->length = (int)(o&0x7F); 83 } else { 84 int num; 85 int len=0; 86 87 for (num = (int)(o&0x7F); num>0; num--) { 88 retval = asn1buf_remove_octet(buf,&o); 89 if(retval) return retval; 90 len = (len<<8) + (int)o; 91 } 92 if (len < 0) 93 return ASN1_OVERRUN; 94 if (!len) 95 t->indef = 1; 96 t->length = len; 97 } 98 } 99 if (t->indef && t->construction != CONSTRUCTED) 100 return ASN1_MISMATCH_INDEF; 101 return 0; 102 } 103 104 asn1_error_code asn1_get_sequence(asn1buf *buf, unsigned int *retlen, int *indef) 105 { 106 taginfo t; 107 asn1_error_code retval; 108 109 retval = asn1_get_tag_2(buf, &t); 110 if (retval) 111 return retval; 112 if (t.asn1class != UNIVERSAL || t.construction != CONSTRUCTED || 113 t.tagnum != ASN1_SEQUENCE) 114 return ASN1_BAD_ID; 115 if (retlen) 116 *retlen = t.length; 117 if (indef) 118 *indef = t.indef; 119 return 0; 120 } 121