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