3 * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #ifdef CONFIG_INTERNAL_X509
23 int asn1_get_next(const u8
*buf
, size_t len
, struct asn1_hdr
*hdr
)
28 os_memset(hdr
, 0, sizeof(*hdr
));
32 hdr
->identifier
= *pos
++;
33 hdr
->class = hdr
->identifier
>> 6;
34 hdr
->constructed
= !!(hdr
->identifier
& (1 << 5));
36 if ((hdr
->identifier
& 0x1f) == 0x1f) {
40 wpa_printf(MSG_DEBUG
, "ASN.1: Identifier "
45 wpa_printf(MSG_MSGDUMP
, "ASN.1: Extended tag data: "
47 hdr
->tag
= (hdr
->tag
<< 7) | (tmp
& 0x7f);
50 hdr
->tag
= hdr
->identifier
& 0x1f;
55 wpa_printf(MSG_DEBUG
, "ASN.1: Reserved length "
59 tmp
&= 0x7f; /* number of subsequent octets */
62 wpa_printf(MSG_DEBUG
, "ASN.1: Too long length field");
67 wpa_printf(MSG_DEBUG
, "ASN.1: Length "
71 hdr
->length
= (hdr
->length
<< 8) | *pos
++;
74 /* Short form - length 0..127 in one octet */
78 if (end
< pos
|| hdr
->length
> (unsigned int) (end
- pos
)) {
79 wpa_printf(MSG_DEBUG
, "ASN.1: Contents underflow");
88 int asn1_get_oid(const u8
*buf
, size_t len
, struct asn1_oid
*oid
,
96 os_memset(oid
, 0, sizeof(*oid
));
98 if (asn1_get_next(buf
, len
, &hdr
) < 0 || hdr
.length
== 0)
101 if (hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_OID
) {
102 wpa_printf(MSG_DEBUG
, "ASN.1: Expected OID - found class %d "
103 "tag 0x%x", hdr
.class, hdr
.tag
);
108 end
= hdr
.payload
+ hdr
.length
;
118 val
= (val
<< 7) | (tmp
& 0x7f);
119 } while (tmp
& 0x80);
121 if (oid
->len
>= ASN1_MAX_OID_LEN
) {
122 wpa_printf(MSG_DEBUG
, "ASN.1: Too long OID value");
127 * The first octet encodes the first two object
128 * identifier components in (X*40) + Y formula.
131 oid
->oid
[0] = val
/ 40;
134 oid
->oid
[1] = val
- oid
->oid
[0] * 40;
137 oid
->oid
[oid
->len
++] = val
;
144 void asn1_oid_to_str(struct asn1_oid
*oid
, char *buf
, size_t len
)
155 for (i
= 0; i
< oid
->len
; i
++) {
156 ret
= os_snprintf(pos
, buf
+ len
- pos
,
158 i
== 0 ? "" : ".", oid
->oid
[i
]);
159 if (ret
< 0 || ret
>= buf
+ len
- pos
)
167 static u8
rotate_bits(u8 octet
)
173 for (i
= 0; i
< 8; i
++) {
184 unsigned long asn1_bit_string_to_long(const u8
*buf
, size_t len
)
186 unsigned long val
= 0;
189 /* BER requires that unused bits are zero, so we can ignore the number
194 val
|= rotate_bits(*pos
++);
196 val
|= ((unsigned long) rotate_bits(*pos
++)) << 8;
198 val
|= ((unsigned long) rotate_bits(*pos
++)) << 16;
200 val
|= ((unsigned long) rotate_bits(*pos
++)) << 24;
202 wpa_printf(MSG_DEBUG
, "X509: %s - some bits ignored "
203 "(BIT STRING length %lu)",
204 __func__
, (unsigned long) len
);
209 #endif /* CONFIG_INTERNAL_X509 */