Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
588bf0f7
Commit
588bf0f7
authored
Oct 13, 2017
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OBJECT IDENTIFIER and RELATIVE-OID API simplified
parent
290e2c7f
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
776 additions
and
792 deletions
+776
-792
ChangeLog
ChangeLog
+1
-0
asn1c/unber.c
asn1c/unber.c
+8
-9
skeletons/INTEGER.c
skeletons/INTEGER.c
+91
-1
skeletons/INTEGER.h
skeletons/INTEGER.h
+8
-2
skeletons/OBJECT_IDENTIFIER.c
skeletons/OBJECT_IDENTIFIER.c
+300
-502
skeletons/OBJECT_IDENTIFIER.h
skeletons/OBJECT_IDENTIFIER.h
+52
-48
skeletons/RELATIVE-OID.c
skeletons/RELATIVE-OID.c
+120
-101
skeletons/RELATIVE-OID.h
skeletons/RELATIVE-OID.h
+4
-4
skeletons/asn_internal.h
skeletons/asn_internal.h
+3
-3
tests/tests-skeletons/check-OIDs.c
tests/tests-skeletons/check-OIDs.c
+189
-122
No files found.
ChangeLog
View file @
588bf0f7
...
...
@@ -9,6 +9,7 @@
NOTABLE:
* converter-sample.c renamed into converter-example.c.
* OBJECT IDENTIFIER and RELATIVE-OID API simplified.
* Added random value generation (-R option to converter-example).
* Added LibFuzzer-based randomized tests for supported transfer syntaxes
(DER, OER, UPER, XER) into tests/tests-randomized. See the following
...
...
asn1c/unber.c
View file @
588bf0f7
...
...
@@ -434,7 +434,7 @@ print_TL(int fin, size_t offset, int level, int constr, ssize_t tlen,
static
int
print_V
(
const
char
*
fname
,
FILE
*
fp
,
ber_tlv_tag_t
tlv_tag
,
ber_tlv_len_t
tlv_len
)
{
asn
1c_integer
_t
*
arcs
=
0
;
/* Object identifier arcs */
asn
_oid_arc
_t
*
arcs
=
0
;
/* Object identifier arcs */
unsigned
char
*
vbuf
=
0
;
asn1p_expr_type_e
etype
=
0
;
asn1c_integer_t
collector
=
0
;
...
...
@@ -577,20 +577,19 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
break
;
case
ASN_BASIC_OBJECT_IDENTIFIER
:
if
(
vbuf
)
{
OBJECT_IDENTIFIER_t
oid
;
in
t
arcno
;
OBJECT_IDENTIFIER_t
oid
=
{
0
,
0
}
;
ssize_
t
arcno
;
oid
.
buf
=
vbuf
;
oid
.
size
=
tlv_len
;
arcno
=
OBJECT_IDENTIFIER_get_arcs
(
&
oid
,
arcs
,
sizeof
(
*
arcs
),
tlv_len
+
1
);
arcno
=
OBJECT_IDENTIFIER_get_arcs
(
&
oid
,
arcs
,
tlv_len
+
1
);
if
(
arcno
>=
0
)
{
assert
(
arcno
<=
(
tlv_len
+
1
));
printf
(
" F>"
);
for
(
i
=
0
;
i
<
arcno
;
i
++
)
{
if
(
i
)
printf
(
"."
);
printf
(
"%
s"
,
asn1p_itoa
(
arcs
[
i
])
);
printf
(
"%
"
PRIu32
,
arcs
[
i
]
);
}
FREEMEM
(
vbuf
);
vbuf
=
0
;
...
...
@@ -605,13 +604,13 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
oid
.
buf
=
vbuf
;
oid
.
size
=
tlv_len
;
arcno
=
RELATIVE_OID_get_arcs
(
&
oid
,
arcs
,
sizeof
(
*
arcs
),
tlv_len
);
arcno
=
RELATIVE_OID_get_arcs
(
&
oid
,
arcs
,
tlv_len
);
if
(
arcno
>=
0
)
{
assert
(
arcno
<=
(
tlv_len
+
1
)
);
assert
(
arcno
<=
tlv_len
);
printf
(
" F>"
);
for
(
i
=
0
;
i
<
arcno
;
i
++
)
{
if
(
i
)
printf
(
"."
);
printf
(
"%
s"
,
asn1p_itoa
(
arcs
[
i
])
);
printf
(
"%
"
PRIu32
,
arcs
[
i
]
);
}
FREEMEM
(
vbuf
);
vbuf
=
0
;
...
...
skeletons/INTEGER.c
View file @
588bf0f7
...
...
@@ -1028,9 +1028,9 @@ asn_strtoimax_lim(const char *str, const char **end, intmax_t *intp) {
intmax_t
value
;
#define ASN1_INTMAX_MAX ((~(uintmax_t)0) >> 1)
const
intmax_t
upper_boundary
=
ASN1_INTMAX_MAX
/
10
;
intmax_t
last_digit_max
=
ASN1_INTMAX_MAX
%
10
;
#undef ASN1_INTMAX_MAX
if
(
str
>=
*
end
)
return
ASN_STRTOX_ERROR_INVAL
;
...
...
@@ -1084,6 +1084,66 @@ asn_strtoimax_lim(const char *str, const char **end, intmax_t *intp) {
return
ASN_STRTOX_OK
;
}
/*
* Parse the number in the given string until the given *end position,
* returning the position after the last parsed character back using the
* same (*end) pointer.
* WARNING: This behavior is different from the standard strtoul/strtoumax(3).
*/
enum
asn_strtox_result_e
asn_strtoumax_lim
(
const
char
*
str
,
const
char
**
end
,
uintmax_t
*
uintp
)
{
uintmax_t
value
;
#define ASN1_UINTMAX_MAX ((~(uintmax_t)0))
const
uintmax_t
upper_boundary
=
ASN1_UINTMAX_MAX
/
10
;
uintmax_t
last_digit_max
=
ASN1_UINTMAX_MAX
%
10
;
#undef ASN1_UINTMAX_MAX
if
(
str
>=
*
end
)
return
ASN_STRTOX_ERROR_INVAL
;
switch
(
*
str
)
{
case
'-'
:
return
ASN_STRTOX_ERROR_INVAL
;
case
'+'
:
str
++
;
if
(
str
>=
*
end
)
{
*
end
=
str
;
return
ASN_STRTOX_EXPECT_MORE
;
}
}
for
(
value
=
0
;
str
<
(
*
end
);
str
++
)
{
switch
(
*
str
)
{
case
0x30
:
case
0x31
:
case
0x32
:
case
0x33
:
case
0x34
:
case
0x35
:
case
0x36
:
case
0x37
:
case
0x38
:
case
0x39
:
{
unsigned
int
d
=
*
str
-
'0'
;
if
(
value
<
upper_boundary
)
{
value
=
value
*
10
+
d
;
}
else
if
(
value
==
upper_boundary
)
{
if
(
d
<=
last_digit_max
)
{
value
=
value
*
10
+
d
;
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
continue
;
default:
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_OK
;
}
enum
asn_strtox_result_e
asn_strtol_lim
(
const
char
*
str
,
const
char
**
end
,
long
*
lp
)
{
intmax_t
value
;
...
...
@@ -1114,6 +1174,36 @@ asn_strtol_lim(const char *str, const char **end, long *lp) {
return
ASN_STRTOX_ERROR_INVAL
;
}
enum
asn_strtox_result_e
asn_strtoul_lim
(
const
char
*
str
,
const
char
**
end
,
unsigned
long
*
ulp
)
{
uintmax_t
value
;
switch
(
asn_strtoumax_lim
(
str
,
end
,
&
value
))
{
case
ASN_STRTOX_ERROR_RANGE
:
return
ASN_STRTOX_ERROR_RANGE
;
case
ASN_STRTOX_ERROR_INVAL
:
return
ASN_STRTOX_ERROR_INVAL
;
case
ASN_STRTOX_EXPECT_MORE
:
return
ASN_STRTOX_EXPECT_MORE
;
case
ASN_STRTOX_OK
:
if
(
value
<=
ULONG_MAX
)
{
*
ulp
=
value
;
return
ASN_STRTOX_OK
;
}
else
{
return
ASN_STRTOX_ERROR_RANGE
;
}
case
ASN_STRTOX_EXTRA_DATA
:
if
(
value
<=
ULONG_MAX
)
{
*
ulp
=
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
else
{
return
ASN_STRTOX_ERROR_RANGE
;
}
}
assert
(
!
"Unreachable"
);
return
ASN_STRTOX_ERROR_INVAL
;
}
int
INTEGER_compare
(
const
asn_TYPE_descriptor_t
*
td
,
const
void
*
aptr
,
const
void
*
bptr
)
{
...
...
skeletons/INTEGER.h
View file @
588bf0f7
...
...
@@ -83,8 +83,14 @@ enum asn_strtox_result_e {
ASN_STRTOX_OK
=
0
,
/* Conversion succeded, number ends at (*end) */
ASN_STRTOX_EXTRA_DATA
=
1
/* Conversion succeded, but the string has extra stuff */
};
enum
asn_strtox_result_e
asn_strtol_lim
(
const
char
*
str
,
const
char
**
end
,
long
*
l
);
enum
asn_strtox_result_e
asn_strtoimax_lim
(
const
char
*
str
,
const
char
**
end
,
intmax_t
*
l
);
enum
asn_strtox_result_e
asn_strtol_lim
(
const
char
*
str
,
const
char
**
end
,
long
*
l
);
enum
asn_strtox_result_e
asn_strtoul_lim
(
const
char
*
str
,
const
char
**
end
,
unsigned
long
*
l
);
enum
asn_strtox_result_e
asn_strtoimax_lim
(
const
char
*
str
,
const
char
**
end
,
intmax_t
*
l
);
enum
asn_strtox_result_e
asn_strtoumax_lim
(
const
char
*
str
,
const
char
**
end
,
uintmax_t
*
l
);
/*
* Convert the integer value into the corresponding enumeration map entry.
...
...
skeletons/OBJECT_IDENTIFIER.c
View file @
588bf0f7
...
...
@@ -55,16 +55,6 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
0
/* No specifics */
};
/*
* Endianness check. Will be optimized out by the compiler.
*/
static
int
little_endian
()
{
int
le_check
=
1
;
return
*
(
char
*
)
&
le_check
;
}
int
OBJECT_IDENTIFIER_constraint
(
asn_TYPE_descriptor_t
*
td
,
const
void
*
sptr
,
asn_app_constraint_failed_f
*
ctfailcb
,
void
*
app_key
)
{
...
...
@@ -88,209 +78,107 @@ OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
return
0
;
}
int
OBJECT_IDENTIFIER_get_single_arc
(
const
uint8_t
*
arcbuf
,
unsigned
int
arclen
,
signed
int
add
,
void
*
rvbufp
,
unsigned
int
rvsize
)
{
const
uint8_t
*
arcend
=
arcbuf
+
arclen
;
/* End of arc */
unsigned
int
cache
=
0
;
/* No more than 14 significant bits */
unsigned
char
*
rvbuf
=
(
unsigned
char
*
)
rvbufp
;
unsigned
char
*
rvstart
=
rvbuf
;
/* Original start of the value buffer */
int
inc
;
/* Return value growth direction */
static
ssize_t
OBJECT_IDENTIFIER_get_first_arcs
(
const
uint8_t
*
arcbuf
,
size_t
arcbuf_len
,
asn_oid_arc_t
*
arc0
,
asn_oid_arc_t
*
arc1
)
{
asn_oid_arc_t
value
;
ssize_t
rd
=
OBJECT_IDENTIFIER_get_single_arc
(
arcbuf
,
arcbuf_len
,
&
value
);
if
(
rd
<=
0
)
return
rd
;
if
(
value
>=
80
)
{
*
arc0
=
2
;
*
arc1
=
value
-
80
;
}
else
if
(
value
>=
40
)
{
*
arc0
=
1
;
*
arc1
=
value
-
40
;
}
else
{
*
arc0
=
0
;
*
arc1
=
value
;
}
rvsize
*=
CHAR_BIT
;
/* bytes to bits */
arclen
*=
7
;
/* bytes to bits */
return
rd
;
}
assert
(
add
<=
0
);
ssize_t
OBJECT_IDENTIFIER_get_single_arc
(
const
uint8_t
*
arcbuf
,
size_t
arcbuf_len
,
asn_oid_arc_t
*
ret_value
)
{
const
uint8_t
*
b
=
arcbuf
;
const
uint8_t
*
arcend
=
arcbuf
+
arcbuf_len
;
/* End of arc */
/*
* The arc has the number of bits
* cannot be represented using supplied return value type.
*/
if
(
arclen
>
rvsize
)
{
if
(
arclen
>
(
rvsize
+
CHAR_BIT
))
{
errno
=
ERANGE
;
/* Overflow */
return
-
1
;
if
(
arcbuf
==
arcend
)
{
return
0
;
}
else
{
/*
* Even if the number of bits in the arc representation
* is higher than the width of supplied * return value
* type, there is still possible to fit it when there
* are few unused high bits in the arc value
* representaion.
*
* Moreover, there is a possibility that the
* number could actually fit the arc space, given
* that add is negative, but we don't handle
* such "temporary lack of precision" situation here.
* May be considered as a bug.
*/
uint8_t
mask
=
(
0xff
<<
(
7
-
(
arclen
-
rvsize
)))
&
0x7f
;
if
((
*
arcbuf
&
mask
))
{
errno
=
ERANGE
;
/* Overflow */
return
-
1
;
}
/* Fool the routine computing unused bits */
arclen
-=
7
;
cache
=
*
arcbuf
&
0x7f
;
arcbuf
++
;
}
}
/* Faster path for common size */
if
(
rvsize
==
(
CHAR_BIT
*
sizeof
(
unsigned
long
))
&&
(
arcend
-
arcbuf
)
<=
(
ssize_t
)
sizeof
(
unsigned
long
))
{
unsigned
long
accum
;
asn_oid_arc_t
accum
;
/* Gather all bits into the accumulator */
for
(
accum
=
cache
;
arcbuf
<
arcend
;
arcbuf
++
)
accum
=
(
accum
<<
7
)
|
(
*
arcbuf
&
~
0x80
);
if
(
accum
<
(
unsigned
)
-
add
||
accum
>
ULONG_MAX
-
(
unsigned
long
)(
-
add
))
{
for
(
accum
=
0
;
b
<
arcend
;
b
++
)
{
accum
=
(
accum
<<
7
)
|
(
*
b
&
~
0x80
);
if
((
*
b
&
0x80
)
==
0
)
{
if
(
accum
<=
ASN_OID_ARC_MAX
)
{
*
ret_value
=
accum
;
return
1
+
(
b
-
arcbuf
);
}
else
{
errno
=
ERANGE
;
/* Overflow */
return
-
1
;
}
*
(
unsigned
long
*
)(
void
*
)
rvbuf
=
accum
-
(
unsigned
long
)(
-
add
);
/* alignment OK! */
return
0
;
}
if
(
little_endian
())
{
/* Little endian (x86) */
/* "Convert" to big endian */
rvbuf
+=
rvsize
/
CHAR_BIT
-
1
;
rvstart
--
;
inc
=
-
1
;
/* Descending */
}
else
{
inc
=
+
1
;
/* Big endian */
}
{
int
bits
;
/* typically no more than 3-4 bits */
/* Clear the high unused bits */
for
(
bits
=
rvsize
-
arclen
;
bits
>
CHAR_BIT
;
rvbuf
+=
inc
,
bits
-=
CHAR_BIT
)
*
rvbuf
=
0
;
/* Fill the body of a value */
for
(;
arcbuf
<
arcend
;
arcbuf
++
)
{
cache
=
(
cache
<<
7
)
|
(
*
arcbuf
&
0x7f
);
bits
+=
7
;
if
(
bits
>=
CHAR_BIT
)
{
bits
-=
CHAR_BIT
;
*
rvbuf
=
(
cache
>>
bits
);
rvbuf
+=
inc
;
}
}
if
(
bits
)
{
*
rvbuf
=
cache
;
rvbuf
+=
inc
;
}
}
if
(
add
)
{
for
(
rvbuf
-=
inc
;
rvbuf
!=
rvstart
;
rvbuf
-=
inc
)
{
int
v
=
add
+
*
rvbuf
;
if
(
v
&
((
unsigned
)
~
0
<<
CHAR_BIT
))
{
*
rvbuf
=
(
unsigned
char
)(
v
+
(
1
<<
CHAR_BIT
));
add
=
-
1
;
}
else
{
*
rvbuf
=
v
;
break
;
}
}
if
(
rvbuf
==
rvstart
)
{
/* No space to carry over */
errno
=
ERANGE
;
/* Overflow */
errno
=
EINVAL
;
return
-
1
;
}
}
return
0
;
}
ssize_t
OBJECT_IDENTIFIER__dump_
arc
(
const
uint8_t
*
arcbuf
,
int
arclen
,
int
add
,
s
tatic
s
size_t
OBJECT_IDENTIFIER__dump_
body
(
const
OBJECT_IDENTIFIER_t
*
st
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
char
scratch
[
64
];
/* Conservative estimate */
unsigned
long
accum
;
/* Bits accumulator */
char
*
p
;
/* Position in the scratch buffer */
char
scratch
[
32
];
asn_oid_arc_t
arc0
,
arc1
;
size_t
produced
=
0
;
size_t
off
=
0
;
ssize_t
rd
;
int
ret
;
if
(
OBJECT_IDENTIFIER_get_single_arc
(
arcbuf
,
arclen
,
add
,
&
accum
,
sizeof
(
accum
)))
rd
=
OBJECT_IDENTIFIER_get_first_arcs
(
st
->
buf
,
st
->
size
,
&
arc0
,
&
arc1
);
if
(
rd
<=
0
)
{
return
-
1
;
}
if
(
accum
)
{
ssize_t
len
;
/* Fill the scratch buffer in reverse. */
p
=
scratch
+
sizeof
(
scratch
);
for
(;
accum
;
accum
/=
10
)
*
(
--
p
)
=
(
char
)(
accum
%
10
)
+
0x30
;
/* Put a digit */
len
=
sizeof
(
scratch
)
-
(
p
-
scratch
);
if
(
cb
(
p
,
len
,
app_key
)
<
0
)
ret
=
snprintf
(
scratch
,
sizeof
(
scratch
),
"%"
PRIu32
".%"
PRIu32
,
arc0
,
arc1
);
if
(
ret
>=
(
ssize_t
)
sizeof
(
scratch
))
{
return
-
1
;
return
len
;
}
else
{
*
scratch
=
0x30
;
if
(
cb
(
scratch
,
1
,
app_key
)
<
0
)
return
-
1
;
return
1
;
}
}
int
OBJECT_IDENTIFIER_print_arc
(
const
uint8_t
*
arcbuf
,
int
arclen
,
int
add
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
if
(
OBJECT_IDENTIFIER__dump_arc
(
arcbuf
,
arclen
,
add
,
cb
,
app_key
)
<
0
)
produced
+=
ret
;
if
(
cb
(
scratch
,
ret
,
app_key
)
<
0
)
return
-
1
;
return
0
;
}
static
ssize_t
OBJECT_IDENTIFIER__dump_body
(
const
OBJECT_IDENTIFIER_t
*
st
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
ssize_t
wrote_len
=
0
;
size_t
startn
;
int
add
=
0
;
size_t
i
;
for
(
i
=
0
,
startn
=
0
;
i
<
st
->
size
;
i
++
)
{
uint8_t
b
=
st
->
buf
[
i
];
if
((
b
&
0x80
))
/* Continuation expected */
continue
;
if
(
startn
==
0
)
{
/*
* First two arcs are encoded through the backdoor.
*/
if
(
i
)
{
add
=
-
80
;
if
(
cb
(
"2"
,
1
,
app_key
)
<
0
)
return
-
1
;
}
else
if
(
b
<=
39
)
{
add
=
0
;
if
(
cb
(
"0"
,
1
,
app_key
)
<
0
)
return
-
1
;
}
else
if
(
b
<
79
)
{
add
=
-
40
;
if
(
cb
(
"1"
,
1
,
app_key
)
<
0
)
return
-
1
;
for
(
off
=
rd
;
;
)
{
asn_oid_arc_t
arc
;
rd
=
OBJECT_IDENTIFIER_get_single_arc
(
st
->
buf
+
off
,
st
->
size
-
off
,
&
arc
);
if
(
rd
<
0
)
{
return
-
1
;
}
else
if
(
rd
==
0
)
{
/* No more arcs. */
break
;
}
else
{
add
=
-
80
;
if
(
cb
(
"2"
,
1
,
app_key
)
<
0
)
return
-
1
;
off
+=
rd
;
assert
(
off
<=
st
->
size
);
ret
=
snprintf
(
scratch
,
sizeof
(
scratch
),
".%"
PRIu32
,
arc
);
if
(
ret
>=
(
ssize_t
)
sizeof
(
scratch
))
{
return
-
1
;
}
produced
+=
ret
;
if
(
cb
(
scratch
,
ret
,
app_key
)
<
0
)
return
-
1
;
}
wrote_len
+=
1
;
}
if
(
cb
(
"."
,
1
,
app_key
)
<
0
)
/* Separate arcs */
if
(
off
!=
st
->
size
)
{
ASN_DEBUG
(
"Could not scan to the end of Object Identifier"
);
return
-
1
;
add
=
OBJECT_IDENTIFIER__dump_arc
(
&
st
->
buf
[
startn
],
i
-
startn
+
1
,
add
,
cb
,
app_key
);
if
(
add
<
0
)
return
-
1
;
wrote_len
+=
1
+
add
;
startn
=
i
+
1
;
add
=
0
;
}
return
wrote_len
;
return
produced
;
}
static
enum
xer_pbd_rval
...
...
@@ -298,38 +186,37 @@ OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const
OBJECT_IDENTIFIER_t
*
st
=
(
OBJECT_IDENTIFIER_t
*
)
sptr
;
const
char
*
chunk_end
=
(
const
char
*
)
chunk_buf
+
chunk_size
;
const
char
*
endptr
;
long
s_arcs
[
10
];
long
*
arcs
=
s_arcs
;
int
arcs_count
;
in
t
ret
;
asn_oid_arc_t
s_arcs
[
10
];
asn_oid_arc_t
*
arcs
=
s_arcs
;
ssize_t
num_arcs
;
ssize_
t
ret
;
(
void
)
td
;
arcs_count
=
OBJECT_IDENTIFIER_parse_arcs
(
num_arcs
=
OBJECT_IDENTIFIER_parse_arcs
(
(
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]),
&
endptr
);
if
(
arcs_count
<
0
)
{
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]),
&
endptr
);
if
(
num_arcs
<
0
)
{
/* Expecting more than zero arcs */
return
XPBD_BROKEN_ENCODING
;
}
else
if
(
arcs_count
==
0
)
{
}
else
if
(
num_arcs
==
0
)
{
return
XPBD_NOT_BODY_IGNORE
;
}
assert
(
endptr
==
chunk_end
);
if
((
size_t
)
arcs_count
>
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]))
{
arcs
=
(
long
*
)
MALLOC
(
arcs_count
*
sizeof
(
long
));
if
((
size_t
)
num_arcs
>
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]))
{
arcs
=
(
asn_oid_arc_t
*
)
MALLOC
(
num_arcs
*
sizeof
(
asn_oid_arc_t
));
if
(
!
arcs
)
return
XPBD_SYSTEM_FAILURE
;
ret
=
OBJECT_IDENTIFIER_parse_arcs
(
(
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
arcs_count
,
&
endptr
);
if
(
ret
!=
arcs_count
)
ret
=
OBJECT_IDENTIFIER_parse_arcs
((
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
num_arcs
,
&
endptr
);
if
(
ret
!=
num_arcs
)
return
XPBD_SYSTEM_FAILURE
;
/* assert?.. */
}
/*
* Convert arcs into BER representation.
*/
ret
=
OBJECT_IDENTIFIER_set_arcs
(
st
,
arcs
,
sizeof
(
*
arcs
),
arcs_count
);
ret
=
OBJECT_IDENTIFIER_set_arcs
(
st
,
arcs
,
num_arcs
);
if
(
arcs
!=
s_arcs
)
FREEMEM
(
arcs
);
return
ret
?
XPBD_SYSTEM_FAILURE
:
XPBD_BODY_CONSUMED
;
...
...
@@ -355,8 +242,9 @@ OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
(
void
)
ilevel
;
(
void
)
flags
;
if
(
!
st
||
!
st
->
buf
)
if
(
!
st
||
!
st
->
buf
)
{
ASN__ENCODE_FAILED
;
}
er
.
encoded
=
OBJECT_IDENTIFIER__dump_body
(
st
,
cb
,
app_key
);
if
(
er
.
encoded
<
0
)
ASN__ENCODE_FAILED
;
...
...
@@ -379,65 +267,64 @@ OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
if
(
cb
(
"{ "
,
2
,
app_key
)
<
0
)
return
-
1
;
if
(
OBJECT_IDENTIFIER__dump_body
(
st
,
cb
,
app_key
)
<
0
)
if
(
OBJECT_IDENTIFIER__dump_body
(
st
,
cb
,
app_key
)
<
0
)
{
return
-
1
;
}
return
(
cb
(
" }"
,
2
,
app_key
)
<
0
)
?
-
1
:
0
;
}
int
OBJECT_IDENTIFIER_get_arcs
(
const
OBJECT_IDENTIFIER_t
*
oid
,
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arc_slots
)
{
void
*
arcs_end
=
(
char
*
)
arcs
+
(
arc_type_size
*
arc_slots
);
int
num_arcs
=
0
;
int
startn
=
0
;
int
add
=
0
;
size_t
i
;
if
(
!
oid
||
!
oid
->
buf
||
(
arc_slots
&&
arc_type_size
<=
1
))
{
ssize_t
OBJECT_IDENTIFIER_get_arcs
(
const
OBJECT_IDENTIFIER_t
*
st
,
asn_oid_arc_t
*
arcs
,
size_t
arc_slots
)
{
asn_oid_arc_t
arc0
,
arc1
;
size_t
num_arcs
=
0
;
size_t
off
;
ssize_t
rd
;
if
(
!
st
||
!
st
->
buf
)
{
errno
=
EINVAL
;
return
-
1
;
}
for
(
i
=
0
;
i
<
oid
->
size
;
i
++
)
{
uint8_t
b
=
oid
->
buf
[
i
];
if
((
b
&
0x80
))
/* Continuation expected */
continue
;
if
(
num_arcs
==
0
)
{
/*
* First two arcs are encoded through the backdoor.
*/
int
first_arc
;
num_arcs
++
;
if
(
!
arc_slots
)
{
num_arcs
++
;
continue
;
}
if
(
i
)
first_arc
=
2
;
else
if
(
b
<=
39
)
first_arc
=
0
;
else
if
(
b
<
79
)
first_arc
=
1
;
else
first_arc
=
2
;
add
=
-
40
*
first_arc
;
memset
(
arcs
,
0
,
arc_type_size
);
*
(
unsigned
char
*
)((
char
*
)
arcs
+
(
little_endian
()
?
0
:
(
arc_type_size
-
1
)))
=
first_arc
;
arcs
=
((
char
*
)
arcs
)
+
arc_type_size
;
}
/* Decode, if has space */
if
(
arcs
<
arcs_end
)
{
if
(
OBJECT_IDENTIFIER_get_single_arc
(
&
oid
->
buf
[
startn
],
i
-
startn
+
1
,
add
,
arcs
,
arc_type_size
))
{
rd
=
OBJECT_IDENTIFIER_get_first_arcs
(
st
->
buf
,
st
->
size
,
&
arc0
,
&
arc1
);
if
(
rd
<=
0
)
{
return
-
1
;
}
startn
=
i
+
1
;
arcs
=
((
char
*
)
arcs
)
+
arc_type_size
;
add
=
0
;
num_arcs
=
2
;
switch
(
arc_slots
)
{
default:
case
2
:
arcs
[
1
]
=
arc1
;
/* Fall through */
case
1
:
arcs
[
0
]
=
arc0
;
/* Fall through */
case
0
:
break
;
}
for
(
off
=
rd
;
;
)
{
asn_oid_arc_t
arc
;
rd
=
OBJECT_IDENTIFIER_get_single_arc
(
st
->
buf
+
off
,
st
->
size
-
off
,
&
arc
);
if
(
rd
<
0
)
{
return
-
1
;
}
else
if
(
rd
==
0
)
{
/* No more arcs. */
break
;
}
else
{
off
+=
rd
;
if
(
num_arcs
<
arc_slots
)
{
arcs
[
num_arcs
]
=
arc
;
}
num_arcs
++
;
}
}
if
(
off
!=
st
->
size
)
{
return
-
1
;
}
return
num_arcs
;
}
...
...
@@ -446,137 +333,74 @@ OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, void *arcs,
/*
* Save the single value as an object identifier arc.
*/
int
OBJECT_IDENTIFIER_set_single_arc
(
uint8_t
*
arcbuf
,
const
void
*
arcval
,
unsigned
int
arcval_size
,
int
prepared_order
)
{
ssize_t
OBJECT_IDENTIFIER_set_single_arc
(
uint8_t
*
arcbuf
,
size_t
arcbuf_len
,
asn_oid_arc_t
value
)
{
/*
* The following conditions must hold:
* assert(arcval);
* assert(arcval_size > 0);
* assert(arcval_size <= 16);
* assert(arcbuf);
*/
const
uint8_t
*
tend
,
*
tp
;
unsigned
int
cache
;
uint8_t
*
bp
=
arcbuf
;
int
bits
;
uint8_t
buffer
[
16
];
if
(
little_endian
()
&&
!
prepared_order
)
{
const
uint8_t
*
a
=
(
const
unsigned
char
*
)
arcval
+
arcval_size
-
1
;
const
uint8_t
*
aend
=
(
const
uint8_t
*
)
arcval
;
uint8_t
*
msb
=
buffer
+
arcval_size
-
1
;
uint8_t
*
tb
;
for
(
tb
=
buffer
;
a
>=
aend
;
tb
++
,
a
--
)
if
((
*
tb
=
*
a
)
&&
(
tb
<
msb
))
msb
=
tb
;
tend
=
&
buffer
[
arcval_size
];
tp
=
msb
;
/* Most significant non-zero byte */
}
else
{
/* Look for most significant non-zero byte */
tend
=
(
const
unsigned
char
*
)
arcval
+
arcval_size
;
for
(
tp
=
(
const
uint8_t
*
)
arcval
;
tp
<
tend
-
1
;
tp
++
)
if
(
*
tp
)
break
;
}
/*
* Split the value in 7-bits chunks.
*/
bits
=
((
tend
-
tp
)
*
CHAR_BIT
)
%
7
;
if
(
bits
)
{
cache
=
*
tp
>>
(
CHAR_BIT
-
bits
);
if
(
cache
)
{
*
bp
++
=
cache
|
0x80
;
cache
=
*
tp
++
;
bits
=
CHAR_BIT
-
bits
;
}
else
{
bits
=
-
bits
;
}
}
else
{
cache
=
0
;
uint8_t
scratch
[((
sizeof
(
value
)
*
CHAR_BIT
+
6
)
/
7
)];
uint8_t
*
scratch_end
=
&
scratch
[
sizeof
(
scratch
)
-
1
];
uint8_t
*
b
;
size_t
result_len
;
uint8_t
mask
;
for
(
b
=
scratch_end
,
mask
=
0
;
;
mask
=
0x80
,
b
--
)
{
*
b
=
mask
|
(
value
&
0x7f
);
value
>>=
7
;
if
(
!
value
)
{
break
;
}
for
(;
tp
<
tend
;
tp
++
)
{
cache
=
(
cache
<<
CHAR_BIT
)
+
*
tp
;
bits
+=
CHAR_BIT
;
while
(
bits
>=
7
)
{
bits
-=
7
;
*
bp
++
=
0x80
|
(
cache
>>
bits
);
}
result_len
=
(
scratch_end
-
b
)
+
1
;
if
(
result_len
>
arcbuf_len
)
{
return
-
1
;
}
if
(
bits
)
*
bp
++
=
cache
;
bp
[
-
1
]
&=
0x7f
;
/* Clear the last bit */
return
bp
-
arcbuf
;
memcpy
(
arcbuf
,
b
,
result_len
);
return
result_len
;
}
int
OBJECT_IDENTIFIER_set_arcs
(
OBJECT_IDENTIFIER_t
*
oid
,
const
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arc_slots
)
{
OBJECT_IDENTIFIER_set_arcs
(
OBJECT_IDENTIFIER_t
*
st
,
const
asn_oid_arc_t
*
arcs
,
size_t
arc_slots
)
{
uint8_t
*
buf
;
uint8_t
*
bp
;
unsigned
int
arc0
;
unsigned
int
arc1
;
unsigned
size
;
unsigned
i
;
if
(
!
oid
||
!
arcs
||
arc_type_size
<
1
||
arc_type_size
>
16
||
arc_slots
<
2
)
{
size_t
wrote
;
asn_oid_arc_t
arc0
;
asn_oid_arc_t
arc1
;
size_t
size
;
size_t
i
;
if
(
!
st
||
!
arcs
||
arc_slots
<
2
)
{
errno
=
EINVAL
;
return
-
1
;
}
switch
(
arc_type_size
)
{
case
sizeof
(
char
):
arc0
=
((
const
unsigned
char
*
)
arcs
)[
0
];
arc1
=
((
const
unsigned
char
*
)
arcs
)[
1
];
break
;
case
sizeof
(
short
):
arc0
=
((
const
unsigned
short
*
)
arcs
)[
0
];
arc1
=
((
const
unsigned
short
*
)
arcs
)[
1
];
break
;
case
sizeof
(
int
):
arc0
=
((
const
unsigned
int
*
)
arcs
)[
0
];
arc1
=
((
const
unsigned
int
*
)
arcs
)[
1
];
break
;
default:
arc1
=
arc0
=
0
;
if
(
little_endian
())
{
/* Little endian (x86) */
const
unsigned
char
*
ps
,
*
pe
;
/* If more significant bytes are present,
* make them > 255 quick */
for
(
ps
=
(
const
unsigned
char
*
)
arcs
+
1
,
pe
=
ps
+
arc_type_size
;
ps
<
pe
;
ps
++
)
arc0
|=
*
ps
,
arc1
|=
*
(
ps
+
arc_type_size
);
arc0
<<=
CHAR_BIT
,
arc1
<<=
CHAR_BIT
;
arc0
=
*
((
const
unsigned
char
*
)
arcs
+
0
);
arc1
=
*
((
const
unsigned
char
*
)
arcs
+
arc_type_size
);
}
else
{
const
unsigned
char
*
ps
,
*
pe
;
/* If more significant bytes are present,
* make them > 255 quick */
for
(
ps
=
(
const
unsigned
char
*
)
arcs
,
pe
=
ps
+
arc_type_size
-
1
;
ps
<
pe
;
ps
++
)
arc0
|=
*
ps
,
arc1
|=
*
(
ps
+
arc_type_size
);
arc0
=
*
((
const
unsigned
char
*
)
arcs
+
arc_type_size
-
1
);
arc1
=
*
((
const
unsigned
char
*
)
arcs
+
(
arc_type_size
<<
1
)
-
1
);
}
}
arc0
=
arcs
[
0
];
arc1
=
arcs
[
1
];
/*
* The previous chapter left us with the first and the second arcs.
* The values are not precise (that is, they are valid only if
* they're less than 255), but OK for the purposes of making
* the sanity test below.
*/
if
(
arc0
<=
1
)
{
if
(
arc1
>=
39
)
{
if
(
arc1
>=
40
)
{
/* 8.19.4: At most 39 subsequent values (including 0) */
errno
=
ERANGE
;
return
-
1
;
}
}
else
if
(
arc0
==
2
)
{
if
(
arc1
>
ASN_OID_ARC_MAX
-
80
)
{
errno
=
ERANGE
;
return
-
1
;
}
}
else
if
(
arc0
>
2
)
{
/* 8.19.4: Only three values are allocated from the root node */
errno
=
ERANGE
;
return
-
1
;
}
/*
* After above tests it is known that the value of arc0 is completely
* trustworthy (0..2). However, the arc1's value is still meaningless.
...
...
@@ -590,81 +414,53 @@ OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned
* * the first value may require more space (+1 byte)
* * the value of the first arc which is in range (0..2)
*/
size
=
((
arc_type_size
*
CHAR_BIT
+
6
)
/
7
)
*
arc_slots
;
size
=
((
sizeof
(
asn_oid_arc_t
)
*
CHAR_BIT
+
6
)
/
7
)
*
arc_slots
;
bp
=
buf
=
(
uint8_t
*
)
MALLOC
(
size
+
1
);
if
(
!
buf
)
{
/* ENOMEM */
return
-
1
;
}
/*
* Encode the first two arcs.
* These require special treatment.
*/
{
uint8_t
*
tp
;
uint8_t
first_value
[
1
+
16
];
/* of two arcs */
uint8_t
*
fv
=
first_value
;
/*
* Simulate first_value = arc0 * 40 + arc1;
*/
/* Copy the second (1'st) arcs[1] into the first_value */
*
fv
++
=
0
;
arcs
=
((
const
char
*
)
arcs
)
+
arc_type_size
;
if
(
little_endian
())
{
const
uint8_t
*
aend
=
(
const
unsigned
char
*
)
arcs
-
1
;
const
uint8_t
*
a1
=
(
const
unsigned
char
*
)
arcs
+
arc_type_size
-
1
;
for
(;
a1
>
aend
;
fv
++
,
a1
--
)
*
fv
=
*
a1
;
}
else
{
const
uint8_t
*
a1
=
(
const
uint8_t
*
)
arcs
;
const
uint8_t
*
aend
=
a1
+
arc_type_size
;
for
(;
a1
<
aend
;
fv
++
,
a1
++
)
*
fv
=
*
a1
;
}
/* Increase the first_value by arc0 */
arc0
*=
40
;
/* (0..80) */
for
(
tp
=
first_value
+
arc_type_size
;
tp
>=
first_value
;
tp
--
)
{
unsigned
int
v
=
*
tp
;
v
+=
arc0
;
*
tp
=
v
;
if
(
v
>=
(
1
<<
CHAR_BIT
))
arc0
=
v
>>
CHAR_BIT
;
else
break
;
wrote
=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
size
,
arc0
*
40
+
arc1
);
if
(
wrote
<=
0
)
{
FREEMEM
(
buf
);
return
-
1
;
}
assert
(
wrote
<=
size
);
bp
+=
wrote
;
size
-=
wrote
;
assert
(
tp
>=
first_value
);
bp
+=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
first_value
,
fv
-
first_value
,
1
);
for
(
i
=
2
;
i
<
arc_slots
;
i
++
)
{
wrote
=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
size
,
arcs
[
i
]);
if
(
wrote
<=
0
)
{
FREEMEM
(
buf
);
return
-
1
;
}
/*
* Save the rest of arcs.
*/
for
(
arcs
=
((
const
char
*
)
arcs
)
+
arc_type_size
,
i
=
2
;
i
<
arc_slots
;
i
++
,
arcs
=
((
const
char
*
)
arcs
)
+
arc_type_size
)
{
bp
+=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
arcs
,
arc_type_size
,
0
);
assert
(
wrote
<=
size
);
bp
+=
wrote
;
size
-=
wrote
;
assert
(
wrote
<=
size
);
}
assert
((
unsigned
)(
bp
-
buf
)
<=
size
);
assert
(
size
>=
0
);
/*
* Replace buffer.
*/
oid
->
size
=
bp
-
buf
;
bp
=
oid
->
buf
;
oid
->
buf
=
buf
;
st
->
size
=
bp
-
buf
;
bp
=
st
->
buf
;
st
->
buf
=
buf
;
st
->
buf
[
st
->
size
]
=
'\0'
;
if
(
bp
)
FREEMEM
(
bp
);
return
0
;
}
int
ssize_t
OBJECT_IDENTIFIER_parse_arcs
(
const
char
*
oid_text
,
ssize_t
oid_txt_length
,
long
*
arcs
,
unsigned
int
arcs_slots
,
const
char
**
opt_oid_text_end
)
{
unsigned
int
arcs_count
=
0
;
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
,
const
char
**
opt_oid_text_end
)
{
size_t
num_arcs
=
0
;
const
char
*
oid_end
;
enum
{
ST_LEADSPACE
,
...
...
@@ -673,7 +469,7 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
ST_WAITDIGITS
/* Next character is expected to be a digit */
}
state
=
ST_LEADSPACE
;
if
(
!
oid_text
||
oid_txt_length
<
-
1
||
(
arcs_
slots
&&
!
arcs
))
{
if
(
!
oid_text
||
oid_txt_length
<
-
1
||
(
arcs_
count
&&
!
arcs
))
{
if
(
opt_oid_text_end
)
*
opt_oid_text_end
=
oid_text
;
errno
=
EINVAL
;
return
-
1
;
...
...
@@ -682,26 +478,27 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
if
(
oid_txt_length
==
-
1
)
oid_txt_length
=
strlen
(
oid_text
);
#define _OID_CAPTURE_ARC(oid_text, oid_end) do { \
#define _OID_CAPTURE_ARC(oid_text, oid_end) \
do { \
const char *endp = oid_end; \
long value;
\
switch(asn_strtol_lim(oid_text, &endp, &value)) {
\
unsigned long value;
\
switch(asn_strtoul_lim(oid_text, &endp, &value)) {
\
case ASN_STRTOX_EXTRA_DATA: \
case ASN_STRTOX_OK: \
if(arcs_count < arcs_slots)
\
arcs[arcs_count] = value;
\
arcs_count++;
\
if(value <= ASN_OID_ARC_MAX) {
\
if(num_arcs < arcs_count) arcs[num_arcs] = value;
\
num_arcs++;
\
oid_text = endp - 1; \
break; \
} \
/* Fall through */
\
case ASN_STRTOX_ERROR_RANGE: \
if(opt_oid_text_end) \
*opt_oid_text_end = oid_text; \
if(opt_oid_text_end) *opt_oid_text_end = oid_text; \
errno = ERANGE; \
return -1; \
case ASN_STRTOX_ERROR_INVAL: \
case ASN_STRTOX_EXPECT_MORE: \
if(opt_oid_text_end) \
*opt_oid_text_end = oid_text; \
if(opt_oid_text_end) *opt_oid_text_end = oid_text; \
errno = EINVAL; \
return -1; \
} \
...
...
@@ -772,7 +569,7 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
return
-
1
;
case
ST_AFTERVALUE
:
case
ST_TAILSPACE
:
return
arcs_count
;
return
num_arcs
;
}
errno
=
EINVAL
;
/* Broken OID */
...
...
@@ -783,9 +580,9 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
* Generate values from the list of interesting values, or just a random
* value up to the upper limit.
*/
static
uint32
_t
OBJECT_IDENTIFIER__biased_random_arc
(
uint32
_t
upper_bound
)
{
static
const
uint16
_t
values
[]
=
{
0
,
1
,
127
,
128
,
129
,
254
,
255
,
256
};
static
asn_oid_arc
_t
OBJECT_IDENTIFIER__biased_random_arc
(
asn_oid_arc
_t
upper_bound
)
{
const
asn_oid_arc
_t
values
[]
=
{
0
,
1
,
127
,
128
,
129
,
254
,
255
,
256
};
size_t
idx
;
switch
(
asn_random_between
(
0
,
2
))
{
...
...
@@ -811,7 +608,7 @@ OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
asn_random_fill_result_t
result_failed
=
{
ARFILL_FAILED
,
0
};
asn_random_fill_result_t
result_skipped
=
{
ARFILL_SKIPPED
,
0
};
OBJECT_IDENTIFIER_t
*
st
;
uint32
_t
arcs
[
5
];
asn_oid_arc
_t
arcs
[
5
];
size_t
arcs_len
=
asn_random_between
(
2
,
5
);
size_t
i
;
...
...
@@ -826,13 +623,13 @@ OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
}
arcs
[
0
]
=
asn_random_between
(
0
,
2
);
arcs
[
1
]
=
OBJECT_IDENTIFIER__biased_random_arc
(
arcs
[
0
]
<=
1
?
39
:
UINT_MAX
);
arcs
[
1
]
=
OBJECT_IDENTIFIER__biased_random_arc
(
arcs
[
0
]
<=
1
?
39
:
(
ASN_OID_ARC_MAX
-
80
)
);
for
(
i
=
2
;
i
<
arcs_len
;
i
++
)
{
arcs
[
i
]
=
OBJECT_IDENTIFIER__biased_random_arc
(
UINT
_MAX
);
arcs
[
i
]
=
OBJECT_IDENTIFIER__biased_random_arc
(
ASN_OID_ARC
_MAX
);
}
if
(
OBJECT_IDENTIFIER_set_arcs
(
st
,
arcs
,
sizeof
(
arcs
[
0
]),
arcs_len
))
{
if
(
OBJECT_IDENTIFIER_set_arcs
(
st
,
arcs
,
arcs_len
))
{
if
(
st
!=
*
sptr
)
{
ASN_STRUCT_FREE
(
*
td
,
st
);
}
...
...
@@ -841,5 +638,6 @@ OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
*
sptr
=
st
;
result_ok
.
length
=
st
->
size
;
return
result_ok
;
}
skeletons/OBJECT_IDENTIFIER.h
View file @
588bf0f7
...
...
@@ -14,6 +14,9 @@
extern
"C"
{
#endif
typedef
uint32_t
asn_oid_arc_t
;
#define ASN_OID_ARC_MAX (~((asn_oid_arc_t)0))
typedef
ASN__PRIMITIVE_TYPE_t
OBJECT_IDENTIFIER_t
;
extern
asn_TYPE_descriptor_t
asn_DEF_OBJECT_IDENTIFIER
;
...
...
@@ -40,33 +43,30 @@ asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
**********************************/
/*
* This function fills an (
_
arcs) array with OBJECT IDENTIFIER arcs
* up to specified (
_
arc_slots) elements.
* This function fills an (arcs) array with OBJECT IDENTIFIER arcs
* up to specified (arc_slots) elements.
*
* EXAMPLE:
* void print_arcs(OBJECT_IDENTIFIER_t *oid) {
* unsigned long fixed_arcs[10]; // Try with fixed space first
* unsigned long *arcs = fixed_arcs;
* int arc_type_size = sizeof(fixed_arcs[0]); // sizeof(long)
* int arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
* int count; // Real number of arcs.
* asn_oid_arc_t fixed_arcs[10]; // Try with fixed space first
* asn_oid_arc_t *arcs = fixed_arcs;
* size_t arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
* ssize_t count; // Real number of arcs.
* int i;
*
* count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
* arc_type_size, arc_slots);
* count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots);
* // If necessary, reallocate arcs array and try again.
* if(count > arc_slots) {
* arc_slots = count;
* arcs = malloc(
arc_type_size
* arc_slots);
* arcs = malloc(
sizeof(asn_oid_arc_t)
* arc_slots);
* if(!arcs) return;
* count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
* arc_type_size, arc_slots);
* count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots);
* assert(count == arc_slots);
* }
*
* // Print the contents of the arcs array.
* for(i = 0; i < count; i++)
* printf("%
d
\n", arcs[i]);
* printf("%
"PRIu32"
\n", arcs[i]);
*
* // Avoid memory leak.
* if(arcs != fixed_arcs) free(arcs);
...
...
@@ -77,13 +77,11 @@ asn_random_fill_f OBJECT_IDENTIFIER_random_fill;
* -1/ERANGE: One or more arcs have value out of array cell type range.
* >=0: Number of arcs contained in the OBJECT IDENTIFIER
*
* WARNING: The function always returns the
re
al number of arcs,
* even if there is no sufficient (
_
arc_slots) provided.
* WARNING: The function always returns the
actu
al number of arcs,
* even if there is no sufficient (arc_slots) provided.
*/
int
OBJECT_IDENTIFIER_get_arcs
(
const
OBJECT_IDENTIFIER_t
*
_oid
,
void
*
_arcs
,
/* e.g., unsigned int arcs[N] */
unsigned
int
_arc_type_size
,
/* e.g., sizeof(arcs[0]) */
unsigned
int
_arc_slots
/* e.g., N */
);
ssize_t
OBJECT_IDENTIFIER_get_arcs
(
const
OBJECT_IDENTIFIER_t
*
oid
,
asn_oid_arc_t
*
arcs
,
size_t
arc_slots
);
/*
* This functions initializes the OBJECT IDENTIFIER object with
...
...
@@ -95,25 +93,13 @@ int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid,
* -1/ENOMEM: Memory allocation failed
* 0: The object was initialized with new arcs.
*/
int
OBJECT_IDENTIFIER_set_arcs
(
OBJECT_IDENTIFIER_t
*
_oid
,
const
void
*
_arcs
,
/* e.g., unsigned int arcs[N] */
unsigned
int
_arc_type_size
,
/* e.g., sizeof(arcs[0]) */
unsigned
int
_arc_slots
/* e.g., N */
);
int
OBJECT_IDENTIFIER_set_arcs
(
OBJECT_IDENTIFIER_t
*
oid
,
const
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
);
/*
* Print the specified OBJECT IDENTIFIER arc.
*/
int
OBJECT_IDENTIFIER_print_arc
(
const
uint8_t
*
arcbuf
,
int
arclen
,
int
add
,
/* Arbitrary offset, required to process the first two arcs */
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
);
/* Same as above, but returns the number of written digits, instead of 0 */
ssize_t
OBJECT_IDENTIFIER__dump_arc
(
const
uint8_t
*
arcbuf
,
int
arclen
,
int
add
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
);
/*
* Parse the OBJECT IDENTIFIER textual representation ("1.3.6.1.4.1.9363").
* No arc can exceed the (0..
signed_long_max) range (typically, 0..2G if L32
).
* No arc can exceed the (0..
ASN_OID_ARC_MAX, which is the same as UINT32_MAX
).
* This function is not specific to OBJECT IDENTIFIER, it may be used to parse
* the RELATIVE-OID data, or any other data consisting of dot-separated
* series of numeric values.
...
...
@@ -129,20 +115,38 @@ ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
* >= 0: Number of arcs contained in the OBJECT IDENTIFIER.
*
* WARNING: The function always returns the real number of arcs,
* even if there is no sufficient (
_
arc_slots) provided.
* This is useful for (
_
arc_slots) value estimation.
* even if there is no sufficient (arc_slots) provided.
* This is useful for (arc_slots) value estimation.
*/
int
OBJECT_IDENTIFIER_parse_arcs
(
const
char
*
oid_text
,
ssize_t
oid_txt_length
,
long
arcs
[],
unsigned
int
arcs_slots
,
const
char
**
opt_oid_text_end
);
ssize_t
OBJECT_IDENTIFIER_parse_arcs
(
const
char
*
oid_text
,
ssize_t
oid_txt_length
,
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
,
const
char
**
opt_oid_text_end
);
/*
* Internal functions.
* Used by RELATIVE-OID implementation in particular.
*/
int
OBJECT_IDENTIFIER_get_single_arc
(
const
uint8_t
*
arcbuf
,
unsigned
int
arclen
,
signed
int
add
,
void
*
value
,
unsigned
int
value_size
);
int
OBJECT_IDENTIFIER_set_single_arc
(
uint8_t
*
arcbuf
,
const
void
*
arcval
,
unsigned
int
arcval_size
,
int
_prepared_order
);
/*
* Retrieve a single arc of size from the (arcbuf) buffer.
* RETURN VALUES:
* -1: Failed to retrieve the value from the (arcbuf).
* >0: Number of bytes consumed from the (arcbuf), <= (arcbuf_len).
*/
ssize_t
OBJECT_IDENTIFIER_get_single_arc
(
const
uint8_t
*
arcbuf
,
size_t
arcbuf_len
,
asn_oid_arc_t
*
ret_value
);
/*
* Write the unterminated arc value into the (arcbuf) which has the size at
* least (arcbuf_len).
* RETURN VALUES:
* -1: (arcbuf_len) size is not sufficient to write the value.
* <n>: Number of bytes appended to the arcbuf (<= arcbuf_len).
*/
ssize_t
OBJECT_IDENTIFIER_set_single_arc
(
uint8_t
*
arcbuf
,
size_t
arcbuf_len
,
asn_oid_arc_t
arc_value
);
#ifdef __cplusplus
}
...
...
skeletons/RELATIVE-OID.c
View file @
588bf0f7
...
...
@@ -58,31 +58,38 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
static
ssize_t
RELATIVE_OID__dump_body
(
const
RELATIVE_OID_t
*
st
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
ssize_t
wrote
=
0
;
ssize_t
ret
;
size_t
startn
;
size_t
i
;
for
(
i
=
0
,
startn
=
0
;
i
<
st
->
size
;
i
++
)
{
uint8_t
b
=
st
->
buf
[
i
];
if
((
b
&
0x80
))
/* Continuation expected */
continue
;
if
(
startn
)
{
/* Separate arcs */
if
(
cb
(
"."
,
1
,
app_key
)
<
0
)
char
scratch
[
32
];
size_t
produced
=
0
;
size_t
off
=
0
;
for
(;;)
{
asn_oid_arc_t
arc
;
ssize_t
rd
=
OBJECT_IDENTIFIER_get_single_arc
(
st
->
buf
+
off
,
st
->
size
-
off
,
&
arc
);
if
(
rd
<
0
)
{
return
-
1
;
}
else
if
(
rd
==
0
)
{
/* No more arcs. */
break
;
}
else
{
int
ret
=
snprintf
(
scratch
,
sizeof
(
scratch
),
"%s%"
PRIu32
,
off
?
"."
:
""
,
arc
);
if
(
ret
>=
(
ssize_t
)
sizeof
(
scratch
))
{
return
-
1
;
wrote
++
;
}
produced
+=
ret
;
off
+=
rd
;
assert
(
off
<=
st
->
size
);
if
(
cb
(
scratch
,
ret
,
app_key
)
<
0
)
return
-
1
;
}
}
ret
=
OBJECT_IDENTIFIER__dump_arc
(
&
st
->
buf
[
startn
],
i
-
startn
+
1
,
0
,
cb
,
app_key
);
if
(
ret
<
0
)
return
-
1
;
wrote
+=
ret
;
startn
=
i
+
1
;
if
(
off
!=
st
->
size
)
{
ASN_DEBUG
(
"Could not scan to the end of Object Identifier"
);
return
-
1
;
}
return
wrote
;
return
produced
;
}
int
...
...
@@ -111,38 +118,38 @@ RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void
RELATIVE_OID_t
*
st
=
(
RELATIVE_OID_t
*
)
sptr
;
const
char
*
chunk_end
=
(
const
char
*
)
chunk_buf
+
chunk_size
;
const
char
*
endptr
;
long
s_arcs
[
6
];
long
*
arcs
=
s_arcs
;
int
arcs_count
;
asn_oid_arc_t
s_arcs
[
6
];
asn_oid_arc_t
*
arcs
=
s_arcs
;
ssize_t
num_arcs
;
int
ret
;
(
void
)
td
;
arcs_count
=
OBJECT_IDENTIFIER_parse_arcs
(
(
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]),
&
endptr
);
if
(
arcs_count
<
0
)
{
num_arcs
=
OBJECT_IDENTIFIER_parse_arcs
(
(
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]),
&
endptr
);
if
(
num_arcs
<
0
)
{
/* Expecting at least one arc arcs */
return
XPBD_BROKEN_ENCODING
;
}
else
if
(
arcs_count
==
0
)
{
}
else
if
(
num_arcs
==
0
)
{
return
XPBD_NOT_BODY_IGNORE
;
}
assert
(
endptr
==
chunk_end
);
if
((
size_t
)
arcs_count
>
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]))
{
arcs
=
(
long
*
)
MALLOC
(
arcs_count
*
sizeof
(
long
));
if
((
size_t
)
num_arcs
>
sizeof
(
s_arcs
)
/
sizeof
(
s_arcs
[
0
]))
{
arcs
=
(
asn_oid_arc_t
*
)
MALLOC
(
num_arcs
*
sizeof
(
arcs
[
0
]
));
if
(
!
arcs
)
return
XPBD_SYSTEM_FAILURE
;
ret
=
OBJECT_IDENTIFIER_parse_arcs
(
(
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
arcs_count
,
&
endptr
);
if
(
ret
!=
arcs_count
)
ret
=
OBJECT_IDENTIFIER_parse_arcs
((
const
char
*
)
chunk_buf
,
chunk_size
,
arcs
,
num_arcs
,
&
endptr
);
if
(
ret
!=
num_arcs
)
{
return
XPBD_SYSTEM_FAILURE
;
/* assert?.. */
}
}
/*
* Convert arcs into BER representation.
*/
ret
=
RELATIVE_OID_set_arcs
(
st
,
arcs
,
sizeof
(
*
arcs
),
arcs_count
);
ret
=
RELATIVE_OID_set_arcs
(
st
,
arcs
,
num_arcs
);
if
(
arcs
!=
s_arcs
)
FREEMEM
(
arcs
);
return
ret
?
XPBD_SYSTEM_FAILURE
:
XPBD_BODY_CONSUMED
;
...
...
@@ -177,48 +184,51 @@ RELATIVE_OID_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
ASN__ENCODED_OK
(
er
);
}
int
RELATIVE_OID_get_arcs
(
const
RELATIVE_OID_t
*
roid
,
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arc_slots
)
{
void
*
arcs_end
=
(
char
*
)
arcs
+
(
arc_slots
*
arc_type_size
);
int
num_arcs
=
0
;
size_t
startn
=
0
;
size_t
i
;
ssize_t
RELATIVE_OID_get_arcs
(
const
RELATIVE_OID_t
*
st
,
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
)
{
size_t
num_arcs
=
0
;
size_t
off
;
if
(
!
roid
||
!
roid
->
buf
)
{
if
(
!
st
||
!
st
->
buf
)
{
errno
=
EINVAL
;
return
-
1
;
}
for
(
i
=
0
;
i
<
roid
->
size
;
i
++
)
{
uint8_t
b
=
roid
->
buf
[
i
];
if
((
b
&
0x80
))
/* Continuation expected */
continue
;
if
(
arcs
<
arcs_end
)
{
if
(
OBJECT_IDENTIFIER_get_single_arc
(
&
roid
->
buf
[
startn
],
i
-
startn
+
1
,
0
,
arcs
,
arc_type_size
))
for
(
off
=
0
;;)
{
asn_oid_arc_t
arc
;
ssize_t
rd
=
OBJECT_IDENTIFIER_get_single_arc
(
st
->
buf
+
off
,
st
->
size
-
off
,
&
arc
);
if
(
rd
<
0
)
{
return
-
1
;
arcs
=
((
char
*
)
arcs
)
+
arc_type_size
;
}
else
if
(
rd
==
0
)
{
/* No more arcs. */
break
;
}
else
{
off
+=
rd
;
if
(
num_arcs
<
arcs_count
)
{
arcs
[
num_arcs
]
=
arc
;
}
num_arcs
++
;
}
}
startn
=
i
+
1
;
if
(
off
!=
st
->
size
)
{
return
-
1
;
}
return
num_arcs
;
}
int
RELATIVE_OID_set_arcs
(
RELATIVE_OID_t
*
roid
,
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arcs_slots
)
{
RELATIVE_OID_set_arcs
(
RELATIVE_OID_t
*
st
,
const
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
)
{
uint8_t
*
buf
;
uint8_t
*
bp
;
unsigned
in
t
size
;
unsigned
in
t
i
;
size_
t
size
;
size_
t
i
;
if
(
roid
==
NULL
||
arcs
==
NULL
||
arc_type_size
<
1
)
{
if
(
!
st
||
!
arcs
)
{
errno
=
EINVAL
;
return
-
1
;
}
...
...
@@ -226,7 +236,7 @@ RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_si
/*
* Roughly estimate the maximum size necessary to encode these arcs.
*/
size
=
((
arc_type_size
*
CHAR_BIT
+
6
)
/
7
)
*
arcs_slots
;
size
=
((
sizeof
(
asn_oid_arc_t
)
*
CHAR_BIT
+
6
)
/
7
)
*
arcs_count
;
bp
=
buf
=
(
uint8_t
*
)
MALLOC
(
size
+
1
);
if
(
!
buf
)
{
/* ENOMEM */
...
...
@@ -236,19 +246,26 @@ RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_si
/*
* Encode the arcs.
*/
for
(
i
=
0
;
i
<
arcs_slots
;
i
++
,
arcs
=
((
char
*
)
arcs
)
+
arc_type_size
)
{
bp
+=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
arcs
,
arc_type_size
,
0
);
for
(
i
=
0
;
i
<
arcs_count
;
i
++
)
{
ssize_t
wrote
=
OBJECT_IDENTIFIER_set_single_arc
(
bp
,
size
,
arcs
[
i
]);
if
(
wrote
<=
0
)
{
FREEMEM
(
buf
);
return
-
1
;
}
assert
((
size_t
)
wrote
<=
size
);
bp
+=
wrote
;
size
-=
wrote
;
}
assert
(
(
unsigned
)(
bp
-
buf
)
<=
size
);
assert
(
size
>=
0
);
/*
* Replace buffer.
*/
roid
->
size
=
(
int
)(
bp
-
buf
);
bp
=
roid
->
buf
;
roid
->
buf
=
buf
;
st
->
size
=
bp
-
buf
;
bp
=
st
->
buf
;
st
->
buf
=
buf
;
st
->
buf
[
st
->
size
]
=
'\0'
;
if
(
bp
)
FREEMEM
(
bp
);
return
0
;
...
...
@@ -258,7 +275,7 @@ RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_si
/*
* Generate values from the list of interesting values, or just a random value.
*/
static
uint32
_t
static
asn_oid_arc
_t
RELATIVE_OID__biased_random_arc
()
{
static
const
uint16_t
values
[]
=
{
0
,
1
,
127
,
128
,
129
,
254
,
255
,
256
};
...
...
@@ -283,8 +300,9 @@ RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
asn_random_fill_result_t
result_skipped
=
{
ARFILL_SKIPPED
,
0
};
RELATIVE_OID_t
*
st
;
const
int
min_arcs
=
1
;
/* A minimum of 1 arc is required */
size_t
arcs_len
=
asn_random_between
(
min_arcs
,
3
);
uint32_t
arcs
[
3
];
asn_oid_arc_t
arcs
[
3
];
size_t
arcs_len
=
asn_random_between
(
min_arcs
,
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
size_t
i
;
(
void
)
constraints
;
...
...
@@ -301,7 +319,7 @@ RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
arcs
[
i
]
=
RELATIVE_OID__biased_random_arc
();
}
if
(
RELATIVE_OID_set_arcs
(
st
,
arcs
,
sizeof
(
arcs
[
0
]),
arcs_len
))
{
if
(
RELATIVE_OID_set_arcs
(
st
,
arcs
,
arcs_len
))
{
if
(
st
!=
*
sptr
)
{
ASN_STRUCT_FREE
(
*
td
,
st
);
}
...
...
@@ -310,5 +328,6 @@ RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
*
sptr
=
st
;
result_ok
.
length
=
st
->
size
;
return
result_ok
;
}
skeletons/RELATIVE-OID.h
View file @
588bf0f7
...
...
@@ -37,12 +37,12 @@ asn_random_fill_f RELATIVE_OID_random_fill;
**********************************/
/* See OBJECT_IDENTIFIER_get_arcs() function in OBJECT_IDENTIFIER.h */
int
RELATIVE_OID_get_arcs
(
const
RELATIVE_OID_t
*
_roid
,
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arc_slots
);
ssize_t
RELATIVE_OID_get_arcs
(
const
RELATIVE_OID_t
*
,
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
);
/* See OBJECT_IDENTIFIER_set_arcs() function in OBJECT_IDENTIFIER.h */
int
RELATIVE_OID_set_arcs
(
RELATIVE_OID_t
*
_roid
,
void
*
arcs
,
unsigned
int
arc_type_size
,
unsigned
int
arcs_slots
);
int
RELATIVE_OID_set_arcs
(
RELATIVE_OID_t
*
,
const
asn_oid_arc_t
*
arcs
,
size_t
arcs_count
);
#ifdef __cplusplus
}
...
...
skeletons/asn_internal.h
View file @
588bf0f7
...
...
@@ -38,7 +38,7 @@ int get_asn1c_environment_version(void); /* Run-time version */
*/
#ifndef ASN_DEBUG
/* If debugging code is not defined elsewhere... */
#if EMIT_ASN_DEBUG == 1
/* And it was asked to emit this code... */
#if
def __GNUC__
#if
__STDC_VERSION__ >= 199901L
#ifdef ASN_THREAD_SAFE
/* Thread safety requires sacrifice in output indentation:
* Retain empty definition of ASN_DEBUG_INDENT_ADD. */
...
...
@@ -55,10 +55,10 @@ int asn_debug_indent;
fprintf(stderr, " (%s:%d)\n", \
__FILE__, __LINE__); \
} while(0)
#else
/* !
__GNUC__
*/
#else
/* !
C99
*/
void
CC_PRINTFLIKE
(
1
,
2
)
ASN_DEBUG_f
(
const
char
*
fmt
,
...);
#define ASN_DEBUG ASN_DEBUG_f
#endif
/*
__GNUC__
*/
#endif
/*
C99
*/
#else
/* EMIT_ASN_DEBUG != 1 */
#if __STDC_VERSION__ >= 199901L
#define ASN_DEBUG(...) do{}while(0)
...
...
tests/tests-skeletons/check-OIDs.c
View file @
588bf0f7
...
...
@@ -17,7 +17,7 @@ static void
check_OID
(
int
lineno
,
uint8_t
*
buf
,
size_t
len
,
unsigned
*
ck_buf
,
int
ck_len
)
{
OBJECT_IDENTIFIER_t
*
oid
;
asn_dec_rval_t
rval
;
u
nsigned
long
arcs
[
10
];
u
int32_t
arcs
[
10
];
int
alen
;
int
i
;
...
...
@@ -41,8 +41,8 @@ check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
printf
(
"
\n
"
);
memset
(
arcs
,
'A'
,
sizeof
(
arcs
));
alen
=
OBJECT_IDENTIFIER_get_arcs
(
oid
,
arcs
,
sizeof
(
arcs
[
0
]),
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
alen
=
OBJECT_IDENTIFIER_get_arcs
(
oid
,
arcs
,
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
assert
(
alen
>
0
);
printf
(
"OBJECT_IDENTIFIER_get_arcs() => {"
);
...
...
@@ -50,7 +50,7 @@ check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
* Make sure they are equivalent.
*/
for
(
i
=
0
;
i
<
alen
;
i
++
)
{
printf
(
" %lu"
,
arcs
[
i
]);
printf
(
" %"
PRIu32
,
arcs
[
i
]);
if
(
alen
==
ck_len
)
{
assert
(
arcs
[
i
]
==
ck_buf
[
i
]);
}
...
...
@@ -62,15 +62,16 @@ check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
}
static
void
check_ROID
(
int
lineno
,
uint8_t
*
buf
,
size_t
len
,
unsigned
*
ck_buf
,
int
ck_len
)
{
check_ROID
(
int
lineno
,
uint8_t
*
buf
,
size_t
len
,
unsigned
*
ck_buf
,
size_t
ck_len
)
{
RELATIVE_OID_t
*
oid
;
asn_dec_rval_t
rval
;
u
nsigned
long
arcs
[
10
];
u
int32_t
arcs
[
10
];
int
alen
;
in
t
i
;
size_
t
i
;
printf
(
"%03d: Checking {"
,
lineno
);
for
(
i
=
0
;
i
<
(
ssize_t
)
len
;
i
++
)
{
printf
(
"%s%02x"
,
i
?
" "
:
""
,
buf
[
i
]);
}
for
(
i
=
0
;
i
<
len
;
i
++
)
{
printf
(
"%s%02x"
,
i
?
" "
:
""
,
buf
[
i
]);
}
printf
(
"} against {"
);
for
(
i
=
0
;
i
<
ck_len
;
i
++
)
{
printf
(
"%s%u"
,
i
?
" "
:
""
,
ck_buf
[
i
]);
}
printf
(
"}
\n
"
);
...
...
@@ -89,8 +90,7 @@ check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
printf
(
"
\n
"
);
memset
(
arcs
,
'A'
,
sizeof
(
arcs
));
alen
=
RELATIVE_OID_get_arcs
(
oid
,
arcs
,
sizeof
(
arcs
[
0
]),
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
alen
=
RELATIVE_OID_get_arcs
(
oid
,
arcs
,
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
assert
(
alen
>
0
);
assert
(
alen
==
ck_len
);
...
...
@@ -99,7 +99,7 @@ check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
*/
printf
(
"RELATIVE_OID_get_arcs() => {"
);
for
(
i
=
0
;
i
<
alen
;
i
++
)
{
printf
(
" %lu"
,
arcs
[
i
]);
printf
(
" %"
PRIu32
,
arcs
[
i
]);
assert
(
arcs
[
i
]
==
ck_buf
[
i
]);
}
printf
(
" }
\n
"
);
...
...
@@ -113,26 +113,24 @@ check_speed() {
int
cycles
=
100000000
;
double
a
,
b
,
c
;
struct
timeval
tv
;
u
nsigned
long
value
;
u
int32_t
value
;
int
i
;
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
0
,
&
value
,
sizeof
(
value
)
);
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
&
value
);
assert
(
ret
==
0
);
assert
(
value
==
0x7040c20d
);
gettimeofday
(
&
tv
,
0
);
a
=
tv
.
tv_sec
+
tv
.
tv_usec
/
1000000
.
0
;
for
(
i
=
0
;
i
<
cycles
;
i
++
)
{
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
0
,
&
value
,
sizeof
(
value
));
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
&
value
);
}
assert
(
ret
==
0
);
assert
(
value
==
0x7040c20d
);
gettimeofday
(
&
tv
,
0
);
b
=
tv
.
tv_sec
+
tv
.
tv_usec
/
1000000
.
0
;
for
(
i
=
0
;
i
<
cycles
;
i
++
)
{
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
0
,
&
value
,
sizeof
(
value
));
ret
=
OBJECT_IDENTIFIER_get_single_arc
(
buf
,
sizeof
(
buf
),
&
value
);
}
assert
(
ret
==
0
);
assert
(
value
==
0x7040c20d
);
...
...
@@ -147,55 +145,66 @@ check_speed() {
return
0
;
}
static
void
check_parse
(
const
char
*
oid_txt
,
int
retval
)
{
#define CHECK_PARSE(a, b) check_parse(__LINE__, a, b)
static
void
check_parse
(
int
lineno
,
const
char
*
oid_txt
,
int
retval
)
{
int
ret
;
long
l
[
2
];
uint32_t
arcs
[
2
];
const
char
*
p
=
oid_txt
-
13
;
assert
(
p
<
oid_txt
);
ret
=
OBJECT_IDENTIFIER_parse_arcs
(
oid_txt
,
-
1
,
l
,
2
,
&
p
);
printf
(
"
[%s] => %d == %d
\n
"
,
oid_txt
,
ret
,
retval
);
ret
=
OBJECT_IDENTIFIER_parse_arcs
(
oid_txt
,
-
1
,
arcs
,
2
,
&
p
);
printf
(
"
%03d: [%s] => %d == %d
\n
"
,
lineno
,
oid_txt
,
ret
,
retval
);
assert
(
ret
==
retval
);
assert
(
p
>=
oid_txt
);
}
static
void
check_xer
(
int
expect_arcs
,
char
*
xer
)
{
static
void
check_xer
(
int
lineno
,
asn_TYPE_descriptor_t
*
td
,
ssize_t
expect_arcs
,
char
*
xer
,
const
asn_oid_arc_t
*
expected_arcs
)
{
asn_dec_rval_t
rc
;
RELATIVE_OID_t
*
st
=
0
;
long
arcs
[
10
];
int
ret
;
int
i
;
printf
(
"[%s] => "
,
xer
);
fflush
(
stdout
);
rc
=
asn_DEF_RELATIVE_OID
.
op
->
xer_decoder
(
0
,
&
asn_DEF_RELATIVE_OID
,
(
void
**
)
&
st
,
"t"
,
xer
,
strlen
(
xer
));
void
*
st
=
0
;
uint32_t
arcs
[
10
];
ssize_t
got_arcs
;
ssize_t
i
;
printf
(
"%03d: [%s] => "
,
lineno
,
xer
);
fflush
(
stdout
);
rc
=
td
->
op
->
xer_decoder
(
0
,
td
,
(
void
**
)
&
st
,
"t"
,
xer
,
strlen
(
xer
));
if
(
expect_arcs
==
-
1
)
{
if
(
rc
.
code
!=
RC_OK
)
{
printf
(
"-1
\n
"
);
ASN_STRUCT_FREE
(
asn_DEF_RELATIVE_OID
,
st
);
ASN_STRUCT_FREE
(
*
td
,
st
);
return
;
}
}
assert
(
rc
.
code
==
RC_OK
);
ret
=
RELATIVE_OID_get_arcs
(
st
,
arcs
,
sizeof
(
arcs
[
0
]),
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
assert
(
ret
<
10
);
if
(
td
==
&
asn_DEF_OBJECT_IDENTIFIER
)
{
got_arcs
=
OBJECT_IDENTIFIER_get_arcs
(
st
,
arcs
,
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
}
else
if
(
td
==
&
asn_DEF_RELATIVE_OID
)
{
got_arcs
=
RELATIVE_OID_get_arcs
(
st
,
arcs
,
sizeof
(
arcs
)
/
sizeof
(
arcs
[
0
]));
}
else
{
assert
(
!
"Unreachable"
);
}
assert
(
got_arcs
<
10
);
if
(
expect_arcs
==
-
1
)
{
assert
(
ret
==
-
1
);
ASN_STRUCT_FREE
(
asn_DEF_RELATIVE_OID
,
st
);
assert
(
got_arcs
==
-
1
);
ASN_STRUCT_FREE
(
*
td
,
st
);
return
;
}
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
for
(
i
=
0
;
i
<
got_arcs
;
i
++
)
{
if
(
i
)
printf
(
"."
);
printf
(
"%ld"
,
arcs
[
i
]);
if
(
arcs
[
i
]
!=
i
+
1
)
printf
(
" != %d
\n
"
,
i
+
1
);
assert
(
arcs
[
i
]
==
i
+
1
);
printf
(
"%"
PRIu32
,
arcs
[
i
]);
if
(
arcs
[
i
]
!=
expected_arcs
[
i
])
{
printf
(
" != %"
PRIu32
"
\n
"
,
expected_arcs
[
i
]
);
}
printf
(
": %d == %d
\n
"
,
ret
,
expect_arcs
);
assert
(
ret
==
expect_arcs
);
ASN_STRUCT_FREE
(
asn_DEF_RELATIVE_OID
,
st
);
assert
(
arcs
[
i
]
==
expected_arcs
[
i
]);
}
printf
(
": %zd == %zd
\n
"
,
got_arcs
,
expect_arcs
);
assert
(
got_arcs
==
expect_arcs
);
ASN_STRUCT_FREE
(
*
td
,
st
);
}
#define CHECK_OID(n) \
...
...
@@ -208,118 +217,176 @@ static void check_xer(int expect_arcs, char *xer) {
static
void
check_binary_parsing
()
{
/* {0 0} */
uint8_t
buf0
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x01
,
/* Length */
0x00
};
uint32_t
buf0_check
[]
=
{
0
,
0
};
/* {joint-iso-itu-t 230 3} */
uint8_t
buf1
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x03
,
/* Length */
0x82
,
0x36
,
0x03
};
unsigned
buf1_check
[]
=
{
2
,
230
,
3
};
/* {8571 3 2} */
uint8_t
buf2
[]
=
{
0x0D
,
/* RELATIVE-OID */
0x04
,
/* Length */
0xC2
,
0x7B
,
0x03
,
0x02
};
unsigned
buf2_check
[]
=
{
8571
,
3
,
2
};
uint32_t
buf1_check
[]
=
{
2
,
230
,
3
};
/* {joint-iso-itu-t 42 } */
uint8_t
buf
3
[]
=
{
uint8_t
buf
2
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x01
,
/* Length */
0x7A
};
u
nsigned
buf3
_check
[]
=
{
2
,
42
};
u
int32_t
buf2
_check
[]
=
{
2
,
42
};
/* {joint-iso-itu-t 25957 } */
uint8_t
buf
4
[]
=
{
uint8_t
buf
3
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x03
,
/* Length */
0x81
,
0x80
+
0x4B
,
0x35
};
u
nsigned
buf4
_check
[]
=
{
2
,
25957
};
u
int32_t
buf3
_check
[]
=
{
2
,
25957
};
/* { jounsigned-iso-itu-t 2 1 1 } */
uint8_t
buf
5
[]
=
{
uint8_t
buf
4
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x03
,
/* Length */
0x52
,
0x01
,
0x01
};
u
nsigned
buf5
_check
[]
=
{
2
,
2
,
1
,
1
};
u
int32_t
buf4
_check
[]
=
{
2
,
2
,
1
,
1
};
/* { jounsigned-iso-itu-t 2 1 0 1 } */
uint8_t
buf
6
[]
=
{
uint8_t
buf
5
[]
=
{
0x06
,
/* OBJECT IDENTIFIER */
0x04
,
/* Length */
0x52
,
0x01
,
0x00
,
0x01
};
unsigned
buf6_check
[]
=
{
2
,
2
,
1
,
0
,
1
};
uint32_t
buf5_check
[]
=
{
2
,
2
,
1
,
0
,
1
};
/* {0 0} */
uint8_t
buf10
[]
=
{
0x0D
,
/* RELATIVE-OID */
0x01
,
/* Length */
0x00
};
uint32_t
buf10_check
[]
=
{
0
};
/* {0 0} */
uint8_t
buf11
[]
=
{
0x0D
,
/* RELATIVE-OID */
0x02
,
/* Length */
0x00
,
0x00
};
uint32_t
buf11_check
[]
=
{
0
,
0
};
/* {8571 3 2} */
uint8_t
buf12
[]
=
{
0x0D
,
/* RELATIVE-OID */
0x04
,
/* Length */
0xC2
,
0x7B
,
0x03
,
0x02
};
uint32_t
buf12_check
[]
=
{
8571
,
3
,
2
};
CHECK_OID
(
0
);
CHECK_OID
(
1
);
CHECK_
R
OID
(
2
);
CHECK_OID
(
2
);
CHECK_OID
(
3
);
CHECK_OID
(
4
);
CHECK_OID
(
5
);
CHECK_OID
(
6
);
CHECK_ROID
(
10
);
CHECK_ROID
(
11
);
CHECK_ROID
(
12
);
}
static
void
check_text_parsing
()
{
check_parse
(
""
,
0
);
check_parse
(
" "
,
0
);
check_parse
(
"."
,
-
1
);
check_parse
(
" ."
,
-
1
);
check_parse
(
".1"
,
-
1
);
check_parse
(
"1."
,
-
1
);
check_parse
(
"1. "
,
-
1
);
check_parse
(
".1. "
,
-
1
);
check_parse
(
" .1. "
,
-
1
);
check_parse
(
" 1"
,
1
);
check_parse
(
" 1.2"
,
2
);
check_parse
(
" 1."
,
-
1
);
check_parse
(
" 1. "
,
-
1
);
check_parse
(
"1. "
,
-
1
);
check_parse
(
"1.2"
,
2
);
check_parse
(
"1.2 "
,
2
);
check_parse
(
"1.2 "
,
2
);
check_parse
(
" 1.2 "
,
2
);
check_parse
(
"1. 2"
,
-
1
);
check_parse
(
"1 .2"
,
-
1
);
check_parse
(
" 1 .2"
,
-
1
);
check_parse
(
" 1 .2 "
,
-
1
);
check_parse
(
"1 .2 "
,
-
1
);
check_parse
(
"1.+1"
,
-
1
);
check_parse
(
"10.30.234.234"
,
4
);
check_parse
(
"10.30.234.234 "
,
4
);
check_parse
(
"10.30.234. 234 "
,
-
1
);
check_parse
(
"10.30.234.234."
,
-
1
);
check_parse
(
"1.2000000000.3"
,
3
);
check_parse
(
"1.2147483647.3"
,
3
);
if
(
sizeof
(
long
)
==
4
)
{
check_parse
(
"1.2147483648.3"
,
-
1
);
/* overflow on ILP32 */
check_parse
(
"1.2147483649.3"
,
-
1
);
/* overflow on ILP32 */
check_parse
(
"1.3000000000.3"
,
-
1
);
check_parse
(
"1.4000000000.3"
,
-
1
);
check_parse
(
"1.5000000000.3"
,
-
1
);
check_parse
(
"1.6000000000.3"
,
-
1
);
check_parse
(
"1.9000000000.3"
,
-
1
);
}
else
if
(
sizeof
(
long
)
==
8
)
{
check_parse
(
"1.2147483648.3"
,
3
);
check_parse
(
"1.9223372036854775807.3"
,
3
);
check_parse
(
"1.9223372036854775808.3"
,
-
1
);
}
check_parse
(
"1.900a0000000.3"
,
-
1
);
check_parse
(
"1.900a.3"
,
-
1
);
CHECK_PARSE
(
""
,
0
);
CHECK_PARSE
(
" "
,
0
);
CHECK_PARSE
(
"."
,
-
1
);
CHECK_PARSE
(
" ."
,
-
1
);
CHECK_PARSE
(
".1"
,
-
1
);
CHECK_PARSE
(
"1."
,
-
1
);
CHECK_PARSE
(
"1. "
,
-
1
);
CHECK_PARSE
(
".1. "
,
-
1
);
CHECK_PARSE
(
" .1. "
,
-
1
);
CHECK_PARSE
(
" 1"
,
1
);
CHECK_PARSE
(
" 1.2"
,
2
);
CHECK_PARSE
(
" 1."
,
-
1
);
CHECK_PARSE
(
" 1. "
,
-
1
);
CHECK_PARSE
(
"1. "
,
-
1
);
CHECK_PARSE
(
"1.2"
,
2
);
CHECK_PARSE
(
"1.2 "
,
2
);
CHECK_PARSE
(
"1.2 "
,
2
);
CHECK_PARSE
(
" 1.2 "
,
2
);
CHECK_PARSE
(
"1. 2"
,
-
1
);
CHECK_PARSE
(
"1 .2"
,
-
1
);
CHECK_PARSE
(
" 1 .2"
,
-
1
);
CHECK_PARSE
(
" 1 .2 "
,
-
1
);
CHECK_PARSE
(
"1 .2 "
,
-
1
);
CHECK_PARSE
(
"1.+1"
,
-
1
);
CHECK_PARSE
(
"2.0"
,
2
);
CHECK_PARSE
(
"2.1"
,
2
);
CHECK_PARSE
(
"10.30.234.234"
,
4
);
CHECK_PARSE
(
"10.30.234.234 "
,
4
);
CHECK_PARSE
(
"10.30.234. 234 "
,
-
1
);
CHECK_PARSE
(
"10.30.234.234."
,
-
1
);
CHECK_PARSE
(
"1.2000000000.3"
,
3
);
CHECK_PARSE
(
"1.2147483647.3"
,
3
);
CHECK_PARSE
(
"1.4294967295.3"
,
3
);
CHECK_PARSE
(
"1.4294967296.3"
,
-
1
);
/* overflow on ILP32 */
CHECK_PARSE
(
"1.3000000000.3"
,
3
);
CHECK_PARSE
(
"1.4000000000.3"
,
3
);
CHECK_PARSE
(
"1.5000000000.3"
,
-
1
);
CHECK_PARSE
(
"1.6000000000.3"
,
-
1
);
CHECK_PARSE
(
"1.9000000000.3"
,
-
1
);
CHECK_PARSE
(
"1.900a0000000.3"
,
-
1
);
CHECK_PARSE
(
"1.900a.3"
,
-
1
);
}
#define CHECK_XER(a, b, c, data) check_xer(__LINE__, &asn_DEF_##a, b, c, data)
static
void
check_xer_parsing
()
{
check_xer
(
-
1
,
"<t></t>"
);
check_xer
(
2
,
"<t>1.2</t>"
);
check_xer
(
3
,
"<t>1.2.3</t>"
);
check_xer
(
3
,
"<t> 1.2.3 </t>"
);
check_xer
(
-
1
,
"<t>1.2.3 1</t>"
);
asn_oid_arc_t
zero_zero
[]
=
{
0
,
0
};
asn_oid_arc_t
zero_one
[]
=
{
0
,
1
};
asn_oid_arc_t
one_zero
[]
=
{
1
,
0
};
asn_oid_arc_t
one_one
[]
=
{
1
,
1
};
asn_oid_arc_t
one_two
[]
=
{
1
,
2
};
asn_oid_arc_t
two_one
[]
=
{
2
,
1
};
asn_oid_arc_t
one_two_three
[]
=
{
1
,
2
,
3
};
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t></t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t>1.</t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t>2.1.</t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
2
,
"<t>0.0</t>"
,
zero_zero
);
CHECK_XER
(
RELATIVE_OID
,
2
,
"<t>0.1</t>"
,
zero_one
);
CHECK_XER
(
RELATIVE_OID
,
2
,
"<t>1.0</t>"
,
one_zero
);
CHECK_XER
(
RELATIVE_OID
,
2
,
"<t>1.2</t>"
,
one_two
);
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t>1.-2</t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t>1.+2</t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
3
,
"<t>1.2.3</t>"
,
one_two_three
);
CHECK_XER
(
RELATIVE_OID
,
3
,
"<t> 1.2.3 </t>"
,
one_two_three
);
CHECK_XER
(
RELATIVE_OID
,
-
1
,
"<t>1.2.3 1</t>"
,
0
);
CHECK_XER
(
RELATIVE_OID
,
2
,
"<t>2.1</t>"
,
two_one
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t></t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>1</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>1.</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>2.1.</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t>0.0</t>"
,
zero_zero
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t>0.1</t>"
,
zero_one
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t>1.0</t>"
,
one_zero
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t>1.1</t>"
,
one_one
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t>1.2</t>"
,
one_two
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>1.-2</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>1.+2</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
3
,
"<t>1.2.3</t>"
,
one_two_three
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
3
,
"<t> 1.2.3 </t>"
,
one_two_three
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
-
1
,
"<t>1.2.3 1</t>"
,
0
);
CHECK_XER
(
OBJECT_IDENTIFIER
,
2
,
"<t> 2.1 </t>"
,
two_one
);
}
int
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment