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 */
63 wpa_printf(MSG_DEBUG
, "ASN.1: Length "
67 hdr
->length
= (hdr
->length
<< 8) | *pos
++;
70 /* Short form - length 0..127 in one octet */
74 if (pos
+ hdr
->length
> end
) {
75 wpa_printf(MSG_DEBUG
, "ASN.1: Contents underflow");
84 int asn1_get_oid(const u8
*buf
, size_t len
, struct asn1_oid
*oid
,
92 os_memset(oid
, 0, sizeof(*oid
));
94 if (asn1_get_next(buf
, len
, &hdr
) < 0 || hdr
.length
== 0)
97 if (hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_OID
) {
98 wpa_printf(MSG_DEBUG
, "ASN.1: Expected OID - found class %d "
99 "tag 0x%x", hdr
.class, hdr
.tag
);
104 end
= hdr
.payload
+ hdr
.length
;
114 val
= (val
<< 7) | (tmp
& 0x7f);
115 } while (tmp
& 0x80);
117 if (oid
->len
>= ASN1_MAX_OID_LEN
) {
118 wpa_printf(MSG_DEBUG
, "ASN.1: Too long OID value");
123 * The first octet encodes the first two object
124 * identifier components in (X*40) + Y formula.
127 oid
->oid
[0] = val
/ 40;
130 oid
->oid
[1] = val
- oid
->oid
[0] * 40;
133 oid
->oid
[oid
->len
++] = val
;
140 void asn1_oid_to_str(struct asn1_oid
*oid
, char *buf
, size_t len
)
151 for (i
= 0; i
< oid
->len
; i
++) {
152 ret
= os_snprintf(pos
, buf
+ len
- pos
,
154 i
== 0 ? "" : ".", oid
->oid
[i
]);
155 if (ret
< 0 || ret
>= buf
+ len
- pos
)
163 static u8
rotate_bits(u8 octet
)
169 for (i
= 0; i
< 8; i
++) {
180 unsigned long asn1_bit_string_to_long(const u8
*buf
, size_t len
)
182 unsigned long val
= 0;
185 /* BER requires that unused bits are zero, so we can ignore the number
190 val
|= rotate_bits(*pos
++);
192 val
|= ((unsigned long) rotate_bits(*pos
++)) << 8;
194 val
|= ((unsigned long) rotate_bits(*pos
++)) << 16;
196 val
|= ((unsigned long) rotate_bits(*pos
++)) << 24;
198 wpa_printf(MSG_DEBUG
, "X509: %s - some bits ignored "
199 "(BIT STRING length %lu)",
200 __func__
, (unsigned long) len
);
205 #endif /* CONFIG_INTERNAL_X509 */