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 asn1_error_code asn1buf_insert_octet
145 	(asn1buf *buf, const int o);
146 /* requires  *buf is allocated
147    effects   Inserts o into the buffer *buf, expanding the buffer if
148              necessary.  Returns ENOMEM memory is exhausted. */
149 #if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS))
150 extern __inline__ asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o)
151 {
152   asn1_error_code retval;
153 
154   retval = asn1buf_ensure_space(buf,1U);
155   if(retval) return retval;
156   *(buf->next) = (char)o;
157   (buf->next)++;
158   return 0;
159 }
160 #endif
161 
162 asn1_error_code asn1buf_insert_octetstring
163 	(asn1buf *buf, const unsigned int len, const asn1_octet *s);
164 /* requires  *buf is allocated
165    modifies  *buf
166    effects   Inserts the contents of s (an octet array of length len)
167               into the buffer *buf, expanding the buffer if necessary.
168 	     Returns ENOMEM if memory is exhausted. */
169 
170 asn1_error_code asn1buf_insert_charstring
171 	(asn1buf *buf, const unsigned int len, const char *s);
172 /* requires  *buf is allocated
173    modifies  *buf
174    effects   Inserts the contents of s (a character array of length len)
175               into the buffer *buf, expanding the buffer if necessary.
176 	     Returns ENOMEM if memory is exhausted. */
177 
178 asn1_error_code asn1buf_remove_octet
179 	(asn1buf *buf, asn1_octet *o);
180 /* requires  *buf is allocated
181    effects   Returns *buf's current octet in *o and advances to
182               the next octet.
183 	     Returns ASN1_OVERRUN if *buf has already been exhausted. */
184 #define asn1buf_remove_octet(buf,o) \
185   (((buf)->next > (buf)->bound) \
186    ? ASN1_OVERRUN \
187    : ((*(o) = (asn1_octet)(*(((buf)->next)++))),0))
188 
189 asn1_error_code asn1buf_remove_octetstring
190 	(asn1buf *buf, const unsigned int len, asn1_octet **s);
191 /* requires  *buf is allocated
192    effects   Removes the next len octets of *buf and returns them in **s.
193 	     Returns ASN1_OVERRUN if there are fewer than len unread octets
194 	      left in *buf.
195 	     Returns ENOMEM if *s could not be allocated. */
196 
197 asn1_error_code asn1buf_remove_charstring
198 	(asn1buf *buf, const unsigned int len,
199 					  char **s);
200 /* requires  *buf is allocated
201    effects   Removes the next len octets of *buf and returns them in **s.
202 	     Returns ASN1_OVERRUN if there are fewer than len unread octets
203 	      left in *buf.
204 	     Returns ENOMEM if *s could not be allocated. */
205 
206 asn1_error_code asn1buf_unparse
207 	(const asn1buf *buf, char **s);
208 /* modifies  *s
209    effects   Returns a human-readable representation of *buf in *s,
210              where each octet in *buf is represented by a character in *s. */
211 
212 asn1_error_code asn1buf_hex_unparse
213 	(const asn1buf *buf, char **s);
214 /* modifies  *s
215    effects   Returns a human-readable representation of *buf in *s,
216              where each octet in *buf is represented by a 2-digit
217 	     hexadecimal number in *s. */
218 
219 asn1_error_code asn12krb5_buf
220 	(const asn1buf *buf, krb5_data **code);
221 /* modifies  *code
222    effects   Instantiates **code with the krb5_data representation of **buf. */
223 
224 
225 int asn1buf_remains
226 	(asn1buf *buf, int indef);
227 /* requires  *buf is a buffer containing an asn.1 structure or array
228    modifies  *buf
229    effects   Returns the number of unprocessed octets remaining in *buf. */
230 
231 #endif
232