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