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