1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2 
3 /* Coding Buffer Specifications */
4 #ifndef __ASN1BUF_H__
5 #define __ASN1BUF_H__
6 
7 #include "k5-int.h"
8 #include "krbasn1.h"
9 
10 typedef struct code_buffer_rep {
11   char *base, *bound, *next;
12 } asn1buf;
13 
14 
15 /**************** Private Procedures ****************/
16 
17 int asn1buf_size
18 	(const asn1buf *buf);
19 /* requires  *buf has been created and not destroyed
20    effects   Returns the total size
21 	(in octets) of buf's octet buffer. */
22 #define asn1buf_size(buf) \
23   (((buf) == NULL || (buf)->base == NULL) \
24    ? 0 \
25    : ((buf)->bound - (buf)->base + 1))
26 
27 int asn1buf_free
28 	(const asn1buf *buf);
29 /* requires  *buf is allocated
30    effects   Returns the number of unused, allocated octets in *buf. */
31 #define asn1buf_free(buf) \
32   (((buf) == NULL || (buf)->base == NULL) \
33    ? 0 \
34    : ((buf)->bound - (buf)->next + 1))
35 
36 
37 asn1_error_code asn1buf_ensure_space
38 	(asn1buf *buf, const unsigned int amount);
39 /* requires  *buf is allocated
40    modifies  *buf
41    effects  If buf has less than amount octets of free space, then it is
42             expanded to have at least amount octets of free space.
43             Returns ENOMEM memory is exhausted. */
44 #define asn1buf_ensure_space(buf,amount) \
45   ((asn1buf_free(buf) < (amount)) \
46    ? (asn1buf_expand((buf), (amount)-asn1buf_free(buf))) \
47    : 0)
48 
49 
50 asn1_error_code asn1buf_expand
51 	(asn1buf *buf, unsigned int inc);
52 /* requires  *buf is allocated
53    modifies  *buf
54    effects   Expands *buf by allocating space for inc more octets.
55              Returns ENOMEM if memory is exhausted. */
56 
57 int asn1buf_len
58 	(const asn1buf *buf);
59 /* requires  *buf is allocated
60    effects   Returns the length of the encoding in *buf. */
61 #define asn1buf_len(buf)	((buf)->next - (buf)->base)
62 
63 /****** End of private procedures *****/
64 
65 /*
66   Overview
67 
68     The coding buffer is an array of char (to match a krb5_data structure)
69      with 3 reference pointers:
70      1) base - The bottom of the octet array.  Used for memory management
71                operations on the array (e.g. alloc, realloc, free).
72      2) next - Points to the next available octet position in the array.
73                During encoding, this is the next free position, and it
74                  advances as octets are added to the array.
75 	       During decoding, this is the next unread position, and it
76                  advances as octets are read from the array.
77      3) bound - Points to the top of the array. Used for bounds-checking.
78 
79     All pointers to encoding buffers should be initalized to NULL.
80 
81   Operations
82 
83     asn1buf_create
84     asn1buf_wrap_data
85     asn1buf_destroy
86     asn1buf_insert_octet
87     asn1buf_insert_charstring
88     asn1buf_remove_octet
89     asn1buf_remove_charstring
90     asn1buf_unparse
91     asn1buf_hex_unparse
92     asn12krb5_buf
93     asn1buf_remains
94 
95     (asn1buf_size)
96     (asn1buf_free)
97     (asn1buf_ensure_space)
98     (asn1buf_expand)
99     (asn1buf_len)
100 */
101 
102 asn1_error_code asn1buf_create
103 	(asn1buf **buf);
104 /* effects   Creates a new encoding buffer pointed to by *buf.
105              Returns ENOMEM if the buffer can't be created. */
106 
107 asn1_error_code asn1buf_wrap_data
108 	(asn1buf *buf, const krb5_data *code);
109 /* requires  *buf has already been allocated
110    effects   Turns *buf into a "wrapper" for *code.  i.e. *buf is set up
111               such that its bottom is the beginning of *code, and its top
112 	      is the top of *code.
113 	     Returns ASN1_MISSING_FIELD if code is empty. */
114 
115 asn1_error_code asn1buf_imbed
116 	(asn1buf *subbuf, const asn1buf *buf,
117 		   const unsigned int length,
118 		   const int indef);
119 /* requires  *subbuf and *buf are allocated
120    effects   *subbuf becomes a sub-buffer of *buf.  *subbuf begins
121               at *buf's current position and is length octets long.
122               (Unless this would exceed the bounds of *buf -- in
123 	      that case, ASN1_OVERRUN is returned)  *subbuf's current
124 	      position starts at the beginning of *subbuf. */
125 
126 asn1_error_code asn1buf_sync
127 	(asn1buf *buf, asn1buf *subbuf, const asn1_class Class,
128 		   const asn1_tagnum lasttag,
129 		   const unsigned int length, const int indef,
130 		   const int seqindef);
131 /* requires  *subbuf is a sub-buffer of *buf, as created by asn1buf_imbed.
132              lasttag is the last tagnumber read.
133    effects   Synchronizes *buf's current position to match that of *subbuf. */
134 
135 asn1_error_code asn1buf_skiptail
136 	(asn1buf *buf, const unsigned int length,
137 		   const int indef);
138 /* requires  *buf is a subbuffer used in a decoding of a
139              constructed indefinite sequence.
140    effects   skips trailing fields. */
141 
142 asn1_error_code asn1buf_destroy
143 	(asn1buf **buf);
144 /* effects   Deallocates **buf, sets *buf to NULL. */
145 
146 asn1_error_code asn1buf_insert_octet
147 	(asn1buf *buf, const int o);
148 /* requires  *buf is allocated
149    effects   Inserts o into the buffer *buf, expanding the buffer if
150              necessary.  Returns ENOMEM memory is exhausted. */
151 #if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS))
152 extern __inline__ asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o)
153 {
154   asn1_error_code retval;
155 
156   retval = asn1buf_ensure_space(buf,1U);
157   if(retval) return retval;
158   *(buf->next) = (char)o;
159   (buf->next)++;
160   return 0;
161 }
162 #endif
163 
164 asn1_error_code asn1buf_insert_octetstring
165 	(asn1buf *buf, const unsigned int len, const asn1_octet *s);
166 /* requires  *buf is allocated
167    modifies  *buf
168    effects   Inserts the contents of s (an octet array of length len)
169               into the buffer *buf, expanding the buffer if necessary.
170 	     Returns ENOMEM if memory is exhausted. */
171 
172 asn1_error_code asn1buf_insert_charstring
173 	(asn1buf *buf, const unsigned int len, const char *s);
174 /* requires  *buf is allocated
175    modifies  *buf
176    effects   Inserts the contents of s (a character array of length len)
177               into the buffer *buf, expanding the buffer if necessary.
178 	     Returns ENOMEM if memory is exhausted. */
179 
180 asn1_error_code asn1buf_remove_octet
181 	(asn1buf *buf, asn1_octet *o);
182 /* requires  *buf is allocated
183    effects   Returns *buf's current octet in *o and advances to
184               the next octet.
185 	     Returns ASN1_OVERRUN if *buf has already been exhausted. */
186 #define asn1buf_remove_octet(buf,o) \
187   (((buf)->next > (buf)->bound) \
188    ? ASN1_OVERRUN \
189    : ((*(o) = (asn1_octet)(*(((buf)->next)++))),0))
190 
191 asn1_error_code asn1buf_remove_octetstring
192 	(asn1buf *buf, const unsigned int len, asn1_octet **s);
193 /* requires  *buf is allocated
194    effects   Removes the next len octets of *buf and returns them in **s.
195 	     Returns ASN1_OVERRUN if there are fewer than len unread octets
196 	      left in *buf.
197 	     Returns ENOMEM if *s could not be allocated. */
198 
199 asn1_error_code asn1buf_remove_charstring
200 	(asn1buf *buf, const unsigned int len,
201 					  char **s);
202 /* requires  *buf is allocated
203    effects   Removes the next len octets of *buf and returns them in **s.
204 	     Returns ASN1_OVERRUN if there are fewer than len unread octets
205 	      left in *buf.
206 	     Returns ENOMEM if *s could not be allocated. */
207 
208 asn1_error_code asn1buf_unparse
209 	(const asn1buf *buf, char **s);
210 /* modifies  *s
211    effects   Returns a human-readable representation of *buf in *s,
212              where each octet in *buf is represented by a character in *s. */
213 
214 asn1_error_code asn1buf_hex_unparse
215 	(const asn1buf *buf, char **s);
216 /* modifies  *s
217    effects   Returns a human-readable representation of *buf in *s,
218              where each octet in *buf is represented by a 2-digit
219 	     hexadecimal number in *s. */
220 
221 asn1_error_code asn12krb5_buf
222 	(const asn1buf *buf, krb5_data **code);
223 /* modifies  *code
224    effects   Instantiates **code with the krb5_data representation of **buf. */
225 
226 
227 int asn1buf_remains
228 	(asn1buf *buf, int indef);
229 /* requires  *buf is a buffer containing an asn.1 structure or array
230    modifies  *buf
231    effects   Returns the number of unprocessed octets remaining in *buf. */
232 
233 #endif
234