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