2 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 RCSID("$Id: der_get.c,v 1.33 2002/09/03 16:21:49 nectar Exp $");
41 * All decoding functions take a pointer `p' to first position in
42 * which to read, from the left, `len' which means the maximum number
43 * of characters we are able to read, `ret' were the value will be
44 * returned and `size' where the number of used bytes is stored.
45 * Either 0 or an error code is returned.
49 der_get_unsigned (const unsigned char *p
, size_t len
,
50 unsigned *ret
, size_t *size
)
56 val
= val
* 256 + *p
++;
58 if(size
) *size
= oldlen
;
63 der_get_int (const unsigned char *p
, size_t len
,
64 int *ret
, size_t *size
)
70 val
= (signed char)*p
++;
72 val
= val
* 256 + *p
++;
75 if(size
) *size
= oldlen
;
80 der_get_length (const unsigned char *p
, size_t len
,
81 size_t *val
, size_t *size
)
98 *val
= ASN1_INDEFINITE
;
105 e
= der_get_unsigned (p
, v
, &tmp
, &l
);
108 if(size
) *size
= l
+ 1;
114 der_get_general_string (const unsigned char *p
, size_t len
,
115 general_string
*str
, size_t *size
)
119 s
= malloc (len
+ 1);
125 if(size
) *size
= len
;
130 der_get_octet_string (const unsigned char *p
, size_t len
,
131 octet_string
*data
, size_t *size
)
134 data
->data
= malloc(len
);
135 if (data
->data
== NULL
&& data
->length
!= 0)
137 memcpy (data
->data
, p
, len
);
138 if(size
) *size
= len
;
143 der_get_oid (const unsigned char *p
, size_t len
,
144 oid
*data
, size_t *size
)
152 data
->components
= malloc(len
* sizeof(*data
->components
));
153 if (data
->components
== NULL
&& len
!= 0)
155 data
->components
[0] = (*p
) / 40;
156 data
->components
[1] = (*p
) % 40;
159 for (n
= 2; len
> 0; ++n
) {
164 u
= u
* 128 + (*p
++ % 128);
165 } while (len
> 0 && p
[-1] & 0x80);
166 data
->components
[n
] = u
;
179 der_get_tag (const unsigned char *p
, size_t len
,
180 Der_class
*class, Der_type
*type
,
181 int *tag
, size_t *size
)
185 *class = (Der_class
)(((*p
) >> 6) & 0x03);
186 *type
= (Der_type
)(((*p
) >> 5) & 0x01);
193 der_match_tag (const unsigned char *p
, size_t len
,
194 Der_class
class, Der_type type
,
195 int tag
, size_t *size
)
203 e
= der_get_tag (p
, len
, &thisclass
, &thistype
, &thistag
, &l
);
205 if (class != thisclass
|| type
!= thistype
)
208 return ASN1_MISPLACED_FIELD
;
210 return ASN1_MISSING_FIELD
;
216 der_match_tag_and_length (const unsigned char *p
, size_t len
,
217 Der_class
class, Der_type type
, int tag
,
218 size_t *length_ret
, size_t *size
)
223 e
= der_match_tag (p
, len
, class, type
, tag
, &l
);
228 e
= der_get_length (p
, len
, length_ret
, &l
);
233 if(size
) *size
= ret
;
238 decode_integer (const unsigned char *p
, size_t len
,
239 int *num
, size_t *size
)
245 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_Integer
, &l
);
250 e
= der_get_length (p
, len
, &reallen
, &l
);
257 e
= der_get_int (p
, reallen
, num
, &l
);
262 if(size
) *size
= ret
;
267 decode_unsigned (const unsigned char *p
, size_t len
,
268 unsigned *num
, size_t *size
)
274 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_Integer
, &l
);
279 e
= der_get_length (p
, len
, &reallen
, &l
);
286 e
= der_get_unsigned (p
, reallen
, num
, &l
);
291 if(size
) *size
= ret
;
296 decode_enumerated (const unsigned char *p
, size_t len
,
297 unsigned *num
, size_t *size
)
303 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_Enumerated
, &l
);
308 e
= der_get_length (p
, len
, &reallen
, &l
);
313 e
= der_get_int (p
, reallen
, num
, &l
);
318 if(size
) *size
= ret
;
323 decode_general_string (const unsigned char *p
, size_t len
,
324 general_string
*str
, size_t *size
)
331 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_GeneralString
, &l
);
337 e
= der_get_length (p
, len
, &slen
, &l
);
345 e
= der_get_general_string (p
, slen
, str
, &l
);
350 if(size
) *size
= ret
;
355 decode_octet_string (const unsigned char *p
, size_t len
,
356 octet_string
*k
, size_t *size
)
363 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_OctetString
, &l
);
369 e
= der_get_length (p
, len
, &slen
, &l
);
377 e
= der_get_octet_string (p
, slen
, k
, &l
);
382 if(size
) *size
= ret
;
387 decode_oid (const unsigned char *p
, size_t len
,
388 oid
*k
, size_t *size
)
395 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_OID
, &l
);
401 e
= der_get_length (p
, len
, &slen
, &l
);
409 e
= der_get_oid (p
, slen
, k
, &l
);
414 if(size
) *size
= ret
;
419 generalizedtime2time (const char *s
, time_t *t
)
423 memset(&tm
, 0, sizeof(tm
));
424 sscanf (s
, "%04d%02d%02d%02d%02d%02dZ",
425 &tm
.tm_year
, &tm
.tm_mon
, &tm
.tm_mday
, &tm
.tm_hour
,
426 &tm
.tm_min
, &tm
.tm_sec
);
433 decode_generalized_time (const unsigned char *p
, size_t len
,
434 time_t *t
, size_t *size
)
443 e
= der_match_tag (p
, len
, UNIV
, PRIM
, UT_GeneralizedTime
, &l
);
449 e
= der_get_length (p
, len
, &slen
, &l
);
456 e
= der_get_octet_string (p
, slen
, &k
, &l
);
461 times
= realloc(k
.data
, k
.length
+ 1);
467 generalizedtime2time (times
, t
);
469 if(size
) *size
= ret
;
475 fix_dce(size_t reallen
, size_t *len
)
477 if(reallen
== ASN1_INDEFINITE
)