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
6d46bc3d
Commit
6d46bc3d
authored
Sep 12, 2017
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
introduce generic encoder
parent
ffb77b08
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
491 additions
and
101 deletions
+491
-101
skeletons/Makefile.am
skeletons/Makefile.am
+8
-1
skeletons/asn_application.c
skeletons/asn_application.c
+294
-0
skeletons/asn_application.h
skeletons/asn_application.h
+90
-2
skeletons/converter-sample.c
skeletons/converter-sample.c
+96
-95
skeletons/file-dependencies
skeletons/file-dependencies
+1
-1
skeletons/per_decoder.h
skeletons/per_decoder.h
+2
-2
No files found.
skeletons/Makefile.am
View file @
6d46bc3d
...
...
@@ -59,7 +59,8 @@ libasn1cskeletons_la_SOURCES = \
VisibleString.c VisibleString.h
\
asn_SEQUENCE_OF.c asn_SEQUENCE_OF.h
\
asn_SET_OF.c asn_SET_OF.h
\
asn_application.h asn_codecs.h
\
asn_application.c asn_application.h
\
asn_codecs.h
\
asn_codecs_prim.c asn_codecs_prim.h
\
asn_internal.h asn_system.h
\
asn_bit_data.c asn_bit_data.h
\
...
...
@@ -88,3 +89,9 @@ libasn1cskeletons_la_SOURCES = \
xer_encoder.c xer_encoder.h
\
xer_support.c xer_support.h
check_PROGRAMS
=
check-converter_sample
LDADD
=
-lm
check_converter_sample_CFLAGS
=
$(SKELETONS_CFLAGS)
-DNO_ASN_PDU
check_converter_sample_SOURCES
=
converter-sample.c
check_converter_sample_LDADD
=
libasn1cskeletons.la
skeletons/asn_application.c
0 → 100644
View file @
6d46bc3d
/*
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <asn_application.h>
#include <errno.h>
static
asn_enc_rval_t
asn_encode_internal
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
enum
asn_transfer_syntax
syntax
,
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
asn_app_consume_bytes_f
*
callback
,
void
*
callback_key
);
struct
callback_count_bytes_key
{
asn_app_consume_bytes_f
*
callback
;
void
*
callback_key
;
size_t
computed_size
;
};
/*
* Encoder which just counts bytes that come through it.
*/
static
int
callback_count_bytes_cb
(
const
void
*
data
,
size_t
size
,
void
*
keyp
)
{
struct
callback_count_bytes_key
*
key
=
keyp
;
int
ret
;
ret
=
key
->
callback
(
data
,
size
,
key
->
callback_key
);
if
(
ret
>=
0
)
{
key
->
computed_size
+=
size
;
}
return
ret
;
}
struct
overrun_encoder_key
{
void
*
buffer
;
size_t
buffer_size
;
size_t
computed_size
;
};
struct
callback_failure_catch_key
{
asn_app_consume_bytes_f
*
callback
;
void
*
callback_key
;
int
callback_failed
;
};
/*
* Encoder which doesn't stop counting bytes
* even if it reaches the end of the buffer.
*/
static
int
overrun_encoder_cb
(
const
void
*
data
,
size_t
size
,
void
*
keyp
)
{
struct
overrun_encoder_key
*
key
=
keyp
;
if
(
key
->
computed_size
+
size
>
key
->
buffer_size
)
{
/*
* Avoid accident on the next call:
* stop adding bytes to the buffer.
*/
key
->
buffer_size
=
0
;
}
else
{
memcpy
((
char
*
)
key
->
buffer
+
key
->
computed_size
,
data
,
size
);
key
->
computed_size
+=
size
;
}
return
0
;
}
/*
* Encoder which help convert the application level encoder failure into EIO.
*/
static
int
callback_failure_catch_cb
(
const
void
*
data
,
size_t
size
,
void
*
keyp
)
{
struct
callback_failure_catch_key
*
key
=
keyp
;
int
ret
;
ret
=
key
->
callback
(
data
,
size
,
key
->
callback_key
);
if
(
ret
<
0
)
{
key
->
callback_failed
=
1
;
}
return
ret
;
}
asn_enc_rval_t
asn_encode
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
enum
asn_transfer_syntax
syntax
,
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
asn_app_consume_bytes_f
*
callback
,
void
*
callback_key
)
{
struct
callback_failure_catch_key
cb_key
;
asn_enc_rval_t
er
;
if
(
!
callback
)
{
errno
=
EINVAL
;
ASN__ENCODE_FAILED
;
}
cb_key
.
callback
=
callback
;
cb_key
.
callback_key
=
callback_key
;
cb_key
.
callback_failed
=
0
;
er
=
asn_encode_internal
(
opt_codec_parameters
,
syntax
,
td
,
sptr
,
callback_failure_catch_cb
,
&
cb_key
);
if
(
cb_key
.
callback_failed
)
{
assert
(
er
.
encoded
==
-
1
);
assert
(
errno
==
EBADF
);
errno
=
EIO
;
}
return
er
;
}
asn_enc_rval_t
asn_encode_to_buffer
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
enum
asn_transfer_syntax
syntax
,
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
void
*
buffer
,
size_t
buffer_size
)
{
struct
overrun_encoder_key
buf_key
;
asn_enc_rval_t
er
;
if
(
buffer_size
>
0
&&
!
buffer
)
{
errno
=
EINVAL
;
ASN__ENCODE_FAILED
;
}
buf_key
.
buffer
=
buffer
;
buf_key
.
buffer_size
=
buffer_size
;
buf_key
.
computed_size
=
0
;
er
=
asn_encode_internal
(
opt_codec_parameters
,
syntax
,
td
,
sptr
,
overrun_encoder_cb
,
&
buf_key
);
assert
(
er
.
encoded
<
0
||
(
size_t
)
er
.
encoded
==
buf_key
.
computed_size
);
return
er
;
}
static
asn_enc_rval_t
asn_encode_internal
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
enum
asn_transfer_syntax
syntax
,
asn_TYPE_descriptor_t
*
td
,
void
*
sptr
,
asn_app_consume_bytes_f
*
callback
,
void
*
callback_key
)
{
asn_enc_rval_t
er
;
enum
xer_encoder_flags_e
xer_flags
=
XER_F_CANONICAL
;
(
void
)
opt_codec_parameters
;
/* Parameters are not checked on encode yet. */
if
(
!
td
||
!
sptr
)
{
errno
=
EINVAL
;
ASN__ENCODE_FAILED
;
}
switch
(
syntax
)
{
case
ATS_BER
:
/* BER is a superset of DER. */
/* Fall through. */
case
ATS_DER
:
if
(
td
->
op
->
der_encoder
)
{
er
=
der_encode
(
td
,
sptr
,
callback
,
callback_key
);
if
(
er
.
encoded
==
-
1
)
{
if
(
er
.
failed_type
&&
er
.
failed_type
->
op
->
der_encoder
)
{
errno
=
EBADF
;
/* Structure has incorrect form. */
}
else
{
errno
=
ENOENT
;
/* DER is not defined for this type. */
}
}
}
else
{
errno
=
ENOENT
;
/* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED
;
}
break
;
case
ATS_CER
:
errno
=
ENOENT
;
/* Transfer syntax is not defined for any type. */
ASN__ENCODE_FAILED
;
#ifdef ASN_DISABLE_OER_SUPPORT
case
ATS_BASIC_OER
:
case
ATS_CANONICAL_OER
:
errno
=
ENOENT
;
/* PER is not defined. */
ASN__ENCODE_FAILED
;
break
;
#else
/* ASN_DISABLE_OER_SUPPORT */
case
ATS_BASIC_OER
:
/* CANONICAL-OER is a superset of BASIC-OER. */
/* Fall through. */
case
ATS_CANONICAL_OER
:
if
(
td
->
op
->
oer_encoder
)
{
er
=
oer_encode
(
td
,
sptr
,
callback
,
callback_key
);
if
(
er
.
encoded
==
-
1
)
{
if
(
er
.
failed_type
&&
er
.
failed_type
->
op
->
oer_encoder
)
{
errno
=
EBADF
;
/* Structure has incorrect form. */
}
else
{
errno
=
ENOENT
;
/* OER is not defined for this type. */
}
}
}
else
{
errno
=
ENOENT
;
/* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED
;
}
break
;
#endif
/* ASN_DISABLE_OER_SUPPORT */
#ifdef ASN_DISABLE_PER_SUPPORT
case
ATS_UNALIGNED_BASIC_PER
:
case
ATS_UNALIGNED_CANONICAL_PER
:
errno
=
ENOENT
;
/* PER is not defined. */
ASN__ENCODE_FAILED
;
break
;
#else
/* ASN_DISABLE_PER_SUPPORT */
case
ATS_UNALIGNED_BASIC_PER
:
/* CANONICAL-UPER is a superset of BASIC-UPER. */
/* Fall through. */
case
ATS_UNALIGNED_CANONICAL_PER
:
if
(
td
->
op
->
uper_encoder
)
{
er
=
uper_encode
(
td
,
sptr
,
callback
,
callback_key
);
if
(
er
.
encoded
==
-
1
)
{
if
(
er
.
failed_type
&&
er
.
failed_type
->
op
->
uper_encoder
)
{
errno
=
EBADF
;
/* Structure has incorrect form. */
}
else
{
errno
=
ENOENT
;
/* UPER is not defined for this type. */
}
}
else
{
ASN_DEBUG
(
"Complete encoded in %ld bits"
,
(
long
)
er
.
encoded
);
if
(
er
.
encoded
==
0
)
{
/* Enforce "Complete Encoding" of X.691 #11.1 */
if
(
callback
(
"
\0
"
,
1
,
callback_key
)
<
0
)
{
errno
=
EBADF
;
ASN__ENCODE_FAILED
;
}
er
.
encoded
=
8
;
/* Exactly 8 zero bits is added. */
}
/* Convert bits into bytes */
er
.
encoded
=
(
er
.
encoded
+
7
)
>>
3
;
}
}
else
{
errno
=
ENOENT
;
/* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED
;
}
break
;
#endif
/* ASN_DISABLE_PER_SUPPORT */
case
ATS_BASIC_XER
:
/* CANONICAL-XER is a superset of BASIC-XER. */
xer_flags
&=
~
XER_F_CANONICAL
;
xer_flags
|=
XER_F_BASIC
;
/* Fall through. */
case
ATS_CANONICAL_XER
:
if
(
td
->
op
->
xer_encoder
)
{
er
=
xer_encode
(
td
,
sptr
,
xer_flags
,
callback
,
callback_key
);
if
(
er
.
encoded
==
-
1
)
{
if
(
er
.
failed_type
&&
er
.
failed_type
->
op
->
xer_encoder
)
{
errno
=
EBADF
;
/* Structure has incorrect form. */
}
else
{
errno
=
ENOENT
;
/* XER is not defined for this type. */
}
}
}
else
{
errno
=
ENOENT
;
/* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED
;
}
break
;
case
ATS_NONSTANDARD_PLAINTEXT
:
if
(
td
->
op
->
print_struct
)
{
struct
callback_count_bytes_key
cb_key
;
cb_key
.
callback
=
callback
;
cb_key
.
callback_key
=
callback_key
;
cb_key
.
computed_size
=
0
;
if
(
td
->
op
->
print_struct
(
td
,
sptr
,
1
,
callback_count_bytes_cb
,
&
cb_key
)
<
0
||
callback_count_bytes_cb
(
"
\n
"
,
1
,
&
cb_key
)
<
0
)
{
errno
=
EBADF
;
/* Structure has incorrect form. */
er
.
encoded
=
-
1
;
er
.
failed_type
=
td
;
er
.
structure_ptr
=
sptr
;
}
else
{
er
.
encoded
=
cb_key
.
computed_size
;
er
.
failed_type
=
0
;
er
.
structure_ptr
=
0
;
}
}
else
{
errno
=
ENOENT
;
/* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED
;
}
break
;
default:
errno
=
ENOENT
;
ASN__ENCODE_FAILED
;
}
return
er
;
}
skeletons/asn_application.h
View file @
6d46bc3d
...
...
@@ -15,6 +15,72 @@
extern
"C"
{
#endif
/*
* A selection of ASN.1 Transfer Syntaxes to use with generalized
* encoder and decoders declared further in this .h file.
*/
enum
asn_transfer_syntax
{
/* Avoid appearance of a default transfer syntax. */
ATS_INVALID
=
0
,
/* Plaintext output, useful for debugging. */
ATS_NONSTANDARD_PLAINTEXT
,
/*
* X.690:
* BER: Basic Encoding Rules.
* DER: Distinguished Encoding Rules.
* CER: Canonical Encoding Rules.
* DER and CER are more strict variants of BER.
*/
ATS_BER
,
ATS_DER
,
ATS_CER
,
/* Only decoding is supported */
/*
* X.696:
* OER: Octet Encoding Rules.
* CANONICAL-OER is a more strict variant of BASIC-OER.
*/
ATS_BASIC_OER
,
ATS_CANONICAL_OER
,
/*
* X.691:
* PER: Packed Encoding Rules.
* CANONICAL-PER is a more strict variant of BASIC-PER.
* NOTE: Produces or consumes a complete encoding (X.691 (08/2015) #11.1).
*/
ATS_UNALIGNED_BASIC_PER
,
ATS_UNALIGNED_CANONICAL_PER
,
/*
* X.693:
* XER: XML Encoding Rules.
* CANONICAL-XER is a more strict variant of BASIC-XER.
*/
ATS_BASIC_XER
,
ATS_CANONICAL_XER
,
};
/*
* A generic encoder for any supported transfer syntax.
* RETURN VALUES:
* The (.encoded) field of the return value is REDEFINED to mean the following:
* >=0: The computed size of the encoded data. Can exceed the (buffer_size).
* -1: Error encoding the structure. See the error code in (errno):
* EINVAL: Incorrect parameters to the function, such as NULLs.
* ENOENT: Encoding transfer syntax is not defined (for this type).
* EBADF: The structure has invalid form or content constraint failed.
* The (.failed_type) and (.structure_ptr) MIGHT be set to the appropriate
* values at the place of failure, if at all possible.
* WARNING: The (.encoded) field of the return value can exceed the buffer_size.
* This is similar to snprintf(3) contract which might return values
* greater than the buffer size.
*/
asn_enc_rval_t
asn_encode_to_buffer
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
/* See asn_codecs.h */
enum
asn_transfer_syntax
,
struct
asn_TYPE_descriptor_s
*
type_to_encode
,
void
*
structure_to_encode
,
void
*
buffer
,
size_t
buffer_size
);
/*
* Generic type of an application-defined callback to return various
* types of data to the application.
...
...
@@ -22,9 +88,30 @@ extern "C" {
* -1: Failed to consume bytes. Abort the mission.
* Non-negative return values indicate success, and ignored.
*/
typedef
int
(
asn_app_consume_bytes_f
)(
const
void
*
buffer
,
size_t
size
,
typedef
int
(
asn_app_consume_bytes_f
)(
const
void
*
buffer
,
size_t
size
,
void
*
application_specific_key
);
/*
* A generic encoder for any supported transfer syntax.
* Returns the comprehensive encoding result descriptor (see asn_codecs.h).
* RETURN VALUES:
* The negative (.encoded) field of the return values is accompanied with the
* following error codes (errno):
* EINVAL: Incorrect parameters to the function, such as NULLs.
* ENOENT: Encoding transfer syntax is not defined (for this type).
* EBADF: The structure has invalid form or content constraint failed.
* EIO: The (callback) has returned negative value during encoding.
*/
asn_enc_rval_t
asn_encode
(
const
asn_codec_ctx_t
*
opt_codec_parameters
,
/* See asn_codecs.h */
enum
asn_transfer_syntax
,
struct
asn_TYPE_descriptor_s
*
type_to_encode
,
void
*
structure_to_encode
,
asn_app_consume_bytes_f
*
callback
,
void
*
callback_key
);
/*
* A callback of this type is called whenever constraint validation fails
* on some ASN.1 type. See "constraints.h" for more details on constraint
...
...
@@ -38,6 +125,7 @@ typedef void (asn_app_constraint_failed_f)(void *application_specific_key,
const
void
*
structure_which_failed_ptr
,
const
char
*
error_message_format
,
...)
GCC_PRINTFLIKE
(
4
,
5
);
#ifdef __cplusplus
}
#endif
...
...
skeletons/converter-sample.c
View file @
6d46bc3d
This diff is collapsed.
Click to expand it.
skeletons/file-dependencies
View file @
6d46bc3d
...
...
@@ -41,7 +41,7 @@ constr_SET.h constr_SET.c
constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h
COMMON-FILES: # THIS IS A SPECIAL SECTION
asn_application.h # Applications should include this file
asn_application.h
asn_application.c
# Applications should include this file
asn_ioc.h # Information Object Classes, runtime support
asn_system.h # Platform-dependent types
asn_codecs.h # Return types of encoders and decoders
...
...
skeletons/per_decoder.h
View file @
6d46bc3d
...
...
@@ -15,8 +15,8 @@ extern "C" {
struct
asn_TYPE_descriptor_s
;
/* Forward declaration */
/*
* Unaligned PER decoder of a "complete encoding" as per X.691
#10
.1.
* On success, this call always returns (.consumed >= 1), as per
X.691#10
.1.3.
* Unaligned PER decoder of a "complete encoding" as per X.691
(08/2015) #11
.1.
* On success, this call always returns (.consumed >= 1), as per
#11
.1.3.
*/
asn_dec_rval_t
uper_decode_complete
(
struct
asn_codec_ctx_s
*
opt_codec_ctx
,
struct
asn_TYPE_descriptor_s
*
type_descriptor
,
/* Type to decode */
...
...
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