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