1/*	$NetBSD: der_length.c,v 1.3 2023/06/19 21:41:42 christos Exp $	*/
2
3/*
4 * Copyright (c) 1997-2005 Kungliga Tekniska H��gskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * 3. Neither the name of the Institute nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38#include "der_locl.h"
39
40__RCSID("$NetBSD: der_length.c,v 1.3 2023/06/19 21:41:42 christos Exp $");
41
42size_t
43_heim_len_unsigned (unsigned val)
44{
45    size_t ret = 0;
46    int last_val_gt_128;
47
48    do {
49	++ret;
50	last_val_gt_128 = (val >= 128);
51	val /= 256;
52    } while (val);
53
54    if(last_val_gt_128)
55	ret++;
56
57    return ret;
58}
59
60size_t
61_heim_len_unsigned64 (uint64_t val)
62{
63    size_t ret = 0;
64    int last_val_gt_128;
65
66    do {
67	++ret;
68	last_val_gt_128 = (val >= 128);
69	val /= 256;
70    } while (val);
71
72    if(last_val_gt_128)
73	ret++;
74
75    return ret;
76}
77
78size_t
79_heim_len_int (int val)
80{
81    unsigned char q;
82    size_t ret = 0;
83
84    if (val >= 0) {
85	do {
86	    q = val % 256;
87	    ret++;
88	    val /= 256;
89	} while(val);
90	if(q >= 128)
91	    ret++;
92    } else {
93	val = ~val;
94	do {
95	    q = ~(val % 256);
96	    ret++;
97	    val /= 256;
98	} while(val);
99	if(q < 128)
100	    ret++;
101    }
102    return ret;
103}
104
105size_t
106_heim_len_int64 (int64_t val)
107{
108    unsigned char q;
109    size_t ret = 0;
110
111    if (val >= 0) {
112	do {
113	    q = val % 256;
114	    ret++;
115	    val /= 256;
116	} while(val);
117	if(q >= 128)
118	    ret++;
119    } else {
120	val = ~val;
121	do {
122	    q = ~(val % 256);
123	    ret++;
124	    val /= 256;
125	} while(val);
126	if(q < 128)
127	    ret++;
128    }
129    return ret;
130}
131
132static size_t
133len_oid (const heim_oid *oid)
134{
135    size_t ret = 1;
136    size_t n;
137
138    for (n = 2; n < oid->length; ++n) {
139	unsigned u = oid->components[n];
140
141	do {
142	    ++ret;
143	    u /= 128;
144	} while(u > 0);
145    }
146    return ret;
147}
148
149size_t
150der_length_len (size_t len)
151{
152    if (len < 128)
153	return 1;
154    else {
155	int ret = 0;
156	do {
157	    ++ret;
158	    len /= 256;
159	} while (len);
160	return ret + 1;
161    }
162}
163
164size_t
165der_length_tag(unsigned int tag)
166{
167    size_t len = 0;
168
169    if(tag <= 30)
170	return 1;
171    while(tag) {
172	tag /= 128;
173	len++;
174    }
175    return len + 1;
176}
177
178size_t
179der_length_integer (const int *data)
180{
181    return _heim_len_int (*data);
182}
183
184size_t
185der_length_integer64 (const int64_t *data)
186{
187    return _heim_len_int64 (*data);
188}
189
190size_t
191der_length_unsigned (const unsigned *data)
192{
193    return _heim_len_unsigned(*data);
194}
195
196size_t
197der_length_unsigned64 (const uint64_t *data)
198{
199    return _heim_len_unsigned64(*data);
200}
201
202size_t
203der_length_enumerated (const unsigned *data)
204{
205  return _heim_len_int (*data);
206}
207
208size_t
209der_length_general_string (const heim_general_string *data)
210{
211    return strlen(*data);
212}
213
214size_t
215der_length_utf8string (const heim_utf8_string *data)
216{
217    return strlen(*data);
218}
219
220size_t
221der_length_printable_string (const heim_printable_string *data)
222{
223    return data->length;
224}
225
226size_t
227der_length_ia5_string (const heim_ia5_string *data)
228{
229    return data->length;
230}
231
232size_t
233der_length_bmp_string (const heim_bmp_string *data)
234{
235    return data->length * 2;
236}
237
238size_t
239der_length_universal_string (const heim_universal_string *data)
240{
241    return data->length * 4;
242}
243
244size_t
245der_length_visible_string (const heim_visible_string *data)
246{
247    return strlen(*data);
248}
249
250size_t
251der_length_octet_string (const heim_octet_string *k)
252{
253    return k->length;
254}
255
256size_t
257der_length_heim_integer (const heim_integer *k)
258{
259    if (k->length == 0)
260	return 1;
261    if (k->negative && k->length == 1 && ((unsigned char *)k->data)[0] == 1)
262        return 1;
263    else if (k->negative)
264	return k->length + (((~(((unsigned char *)k->data)[0])) & 0x80) ? 0 : 1);
265    else
266	return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
267}
268
269size_t
270der_length_oid (const heim_oid *k)
271{
272    return len_oid (k);
273}
274
275size_t
276der_length_generalized_time (const time_t *t)
277{
278    heim_octet_string k;
279    size_t ret;
280
281    _heim_time2generalizedtime (*t, &k, 1);
282    ret = k.length;
283    free(k.data);
284    return ret;
285}
286
287size_t
288der_length_utctime (const time_t *t)
289{
290    heim_octet_string k;
291    size_t ret;
292
293    _heim_time2generalizedtime (*t, &k, 0);
294    ret = k.length;
295    free(k.data);
296    return ret;
297}
298
299size_t
300der_length_boolean (const int *k)
301{
302    return 1;
303}
304
305size_t
306der_length_bit_string (const heim_bit_string *k)
307{
308    return (k->length + 7) / 8 + 1;
309}
310