changed `struct fd_set' to `fd_set'
[heimdal.git] / lib / asn1 / der_put.c
blob72acfe175fab1fa604cb917638792cc8dc347f21
1 /*
2 * Copyright (c) 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "der_locl.h"
41 RCSID("$Id$");
44 * All encoding functions take a pointer `p' to first position in
45 * which to write, from the right, `len' which means the maximum
46 * number of characters we are able to write and return an int
47 * indicating how many actually got written, or <0 in case of errors.
50 int
51 der_put_int (unsigned char *p, size_t len, unsigned val, size_t *size)
53 unsigned char *base = p;
55 if (val) {
56 while (len > 0 && val) {
57 *p-- = val % 256;
58 val /= 256;
59 --len;
61 if (val)
62 return ASN1_OVERFLOW;
63 else {
64 *size = base - p;
65 return 0;
67 } else if (len < 1)
68 return ASN1_OVERFLOW;
69 else {
70 *p = 0;
71 *size = 1;
72 return 0;
76 int
77 der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
79 if (val < 128) {
80 if (len < 1)
81 return ASN1_OVERFLOW;
82 else {
83 *p = val;
84 *size = 1;
85 return 0;
87 } else {
88 size_t l;
89 int e;
91 e = der_put_int (p, len - 1, val, &l);
92 if (e)
93 return e;
94 p -= l;
95 *p = 0x80 | l;
96 *size = l + 1;
97 return 0;
102 der_put_general_string (unsigned char *p, size_t len,
103 general_string *str, size_t *size)
105 size_t slen = strlen(*str);
106 size_t l;
107 int e;
109 if (len < slen)
110 return ASN1_OVERFLOW;
111 p -= slen;
112 len -= slen;
113 memcpy (p+1, *str, slen);
114 e = der_put_length (p, len, slen, &l);
115 if(e)
116 return e;
117 *size = slen + l;
118 return 0;
122 der_put_octet_string (unsigned char *p, size_t len,
123 octet_string *data, size_t *size)
125 size_t l;
126 int e;
128 if (len < data->length)
129 return ASN1_OVERFLOW;
130 p -= data->length;
131 len -= data->length;
132 memcpy (p+1, data->data, data->length);
133 e = der_put_length (p, len, data->length, &l);
134 if(e)
135 return e;
136 *size = l + data->length;
137 return 0;
141 der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
142 int tag, size_t *size)
144 if (len < 1)
145 return ASN1_OVERFLOW;
146 *p = (class << 6) | (type << 5) | tag; /* XXX */
147 *size = 1;
148 return 0;
152 der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
153 Der_class class, Der_type type, int tag, size_t *size)
155 size_t ret = 0;
156 size_t l;
157 int e;
159 e = der_put_length (p, len, len_val, &l);
160 if(e)
161 return e;
162 p -= l;
163 len -= l;
164 ret += l;
165 e = der_put_tag (p, len, class, type, tag, &l);
166 if(e)
167 return e;
168 p -= l;
169 len -= l;
170 ret += l;
171 *size = ret;
172 return 0;
176 encode_integer (unsigned char *p, size_t len, unsigned *data, size_t *size)
178 unsigned num = *data;
179 size_t ret = 0;
180 size_t l;
181 int e;
183 e = der_put_int (p, len, num, &l);
184 if(e)
185 return e;
186 p -= l;
187 len -= l;
188 ret += l;
189 e = der_put_length (p, len, l, &l);
190 if (e)
191 return e;
192 p -= l;
193 len -= l;
194 ret += l;
195 e = der_put_tag (p, len, UNIV, PRIM, UT_Integer, &l);
196 if (e)
197 return e;
198 p -= l;
199 len -= l;
200 ret += l;
201 *size = ret;
202 return 0;
206 encode_general_string (unsigned char *p, size_t len,
207 general_string *data, size_t *size)
209 size_t ret = 0;
210 size_t l;
211 int e;
213 e = der_put_general_string (p, len, data, &l);
214 if (e)
215 return e;
216 p -= l;
217 len -= l;
218 ret += l;
219 e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
220 if (e)
221 return e;
222 p -= l;
223 len -= l;
224 ret += l;
225 *size = ret;
226 return 0;
230 encode_octet_string (unsigned char *p, size_t len,
231 octet_string *k, size_t *size)
233 size_t ret = 0;
234 size_t l;
235 int e;
237 e = der_put_octet_string (p, len, k, &l);
238 if (e)
239 return e;
240 p -= l;
241 len -= l;
242 ret += l;
243 e = der_put_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
244 if (e)
245 return e;
246 p -= l;
247 len -= l;
248 ret += l;
249 *size = ret;
250 return 0;
253 void
254 time2generalizedtime (time_t t, octet_string *s)
256 struct tm *tm;
258 s->data = malloc(16);
259 s->length = 15;
260 tm = gmtime (&t);
261 sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900,
262 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
263 tm->tm_sec);
267 encode_generalized_time (unsigned char *p, size_t len, time_t *t, size_t *size)
269 size_t ret = 0;
270 size_t l;
271 octet_string k;
272 int e;
274 time2generalizedtime (*t, &k);
275 e = der_put_octet_string (p, len, &k, &l);
276 free (k.data);
277 if (e)
278 return e;
279 p -= l;
280 len -= l;
281 ret += l;
282 e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
283 if (e)
284 return e;
285 p -= l;
286 len -= l;
287 ret += l;
288 *size = ret;
289 return 0;