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.
20 int asn1_get_next(const u8
*buf
, size_t len
, struct asn1_hdr
*hdr
)
25 os_memset(hdr
, 0, sizeof(*hdr
));
29 hdr
->identifier
= *pos
++;
30 hdr
->class = hdr
->identifier
>> 6;
31 hdr
->constructed
= !!(hdr
->identifier
& (1 << 5));
33 if ((hdr
->identifier
& 0x1f) == 0x1f) {
37 wpa_printf(MSG_DEBUG
, "ASN.1: Identifier "
42 wpa_printf(MSG_MSGDUMP
, "ASN.1: Extended tag data: "
44 hdr
->tag
= (hdr
->tag
<< 7) | (tmp
& 0x7f);
47 hdr
->tag
= hdr
->identifier
& 0x1f;
52 wpa_printf(MSG_DEBUG
, "ASN.1: Reserved length "
56 tmp
&= 0x7f; /* number of subsequent octets */
59 wpa_printf(MSG_DEBUG
, "ASN.1: Too long length field");
64 wpa_printf(MSG_DEBUG
, "ASN.1: Length "
68 hdr
->length
= (hdr
->length
<< 8) | *pos
++;
71 /* Short form - length 0..127 in one octet */
75 if (end
< pos
|| hdr
->length
> (unsigned int) (end
- pos
)) {
76 wpa_printf(MSG_DEBUG
, "ASN.1: Contents underflow");
85 int asn1_parse_oid(const u8
*buf
, size_t len
, struct asn1_oid
*oid
)
91 os_memset(oid
, 0, sizeof(*oid
));
103 val
= (val
<< 7) | (tmp
& 0x7f);
104 } while (tmp
& 0x80);
106 if (oid
->len
>= ASN1_MAX_OID_LEN
) {
107 wpa_printf(MSG_DEBUG
, "ASN.1: Too long OID value");
112 * The first octet encodes the first two object
113 * identifier components in (X*40) + Y formula.
116 oid
->oid
[0] = val
/ 40;
119 oid
->oid
[1] = val
- oid
->oid
[0] * 40;
122 oid
->oid
[oid
->len
++] = val
;
129 int asn1_get_oid(const u8
*buf
, size_t len
, struct asn1_oid
*oid
,
134 if (asn1_get_next(buf
, len
, &hdr
) < 0 || hdr
.length
== 0)
137 if (hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_OID
) {
138 wpa_printf(MSG_DEBUG
, "ASN.1: Expected OID - found class %d "
139 "tag 0x%x", hdr
.class, hdr
.tag
);
143 *next
= hdr
.payload
+ hdr
.length
;
145 return asn1_parse_oid(hdr
.payload
, hdr
.length
, oid
);
149 void asn1_oid_to_str(struct asn1_oid
*oid
, char *buf
, size_t len
)
160 for (i
= 0; i
< oid
->len
; i
++) {
161 ret
= os_snprintf(pos
, buf
+ len
- pos
,
163 i
== 0 ? "" : ".", oid
->oid
[i
]);
164 if (ret
< 0 || ret
>= buf
+ len
- pos
)
172 static u8
rotate_bits(u8 octet
)
178 for (i
= 0; i
< 8; i
++) {
189 unsigned long asn1_bit_string_to_long(const u8
*buf
, size_t len
)
191 unsigned long val
= 0;
194 /* BER requires that unused bits are zero, so we can ignore the number
199 val
|= rotate_bits(*pos
++);
201 val
|= ((unsigned long) rotate_bits(*pos
++)) << 8;
203 val
|= ((unsigned long) rotate_bits(*pos
++)) << 16;
205 val
|= ((unsigned long) rotate_bits(*pos
++)) << 24;
207 wpa_printf(MSG_DEBUG
, "X509: %s - some bits ignored "
208 "(BIT STRING length %lu)",
209 __func__
, (unsigned long) len
);