Giter Club home page Giter Club logo

asn1rs's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar jkalez avatar kellerkindt avatar nicceboy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

asn1rs's Issues

Improve error messages for failed conversions

I was really excited when I found this project, because I work on a project that involves parsing data structures defined in an ASN.1 UPER file.

When I tried to run asn1rs -t rust ./src ./SAE_J2735_ASN.asn, I got the following backtrace with no useful information about what exactly caused the failure, at least not that I could discern.

Failed to convert SAE_J2735_ASN.asn, reason: Model(UnexpectedToken(stack backtrace:
   0: <asn1rs::model::Model<asn1rs::model::Asn>>::try_from::h36a0d20e67a03670 (0x56555557ce6e)
   1: asn1rs::converter::convert_to_rust::h8eb6f104679bc63e (0x56555556a584)
   2: asn1rs::main::he3fecb671a1b975a (0x56555559a7bd)
   3: std::rt::lang_start::{{closure}}::hc542518d32103aaa (0x565555569913)
   4: std::rt::lang_start_internal::{{closure}}::h8ad4264c6b68797c (0x565555628183)
             at src/libstd/rt.rs:49
      std::panicking::try::do_call::h7a0381557c6c2cee
             at src/libstd/panicking.rs:297
   5: __rust_maybe_catch_panic (0x56555562aafa)
             at src/libpanic_unwind/lib.rs:92
   6: std::panicking::try::h72cb0fef6e9c0ab1 (0x565555628cd6)
             at src/libstd/panicking.rs:276
      std::panic::catch_unwind::hbff071ae76e6f224
             at src/libstd/panic.rs:388
      std::rt::lang_start_internal::he0d8d06abc6f912f
             at src/libstd/rt.rs:48
   7: main (0x56555559aca2)
   8: __libc_start_main (0x7efbff50409b)
   9: _start (0x5655555611aa)
  10: <unknown> (0x0), Text("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_")))

Error parsing INTEGER with 64-bit value range

I'm trying to use asn1rs 0.2.2 with the following ASN.1 subtype definition:

Uint64 ::= INTEGER (0..18446744073709551615)

when I run asn1rs from the shell I get:

[tmp]$ asn1rs --version
asn1rs 0.2.2
[tmp]$ asn1rs . ../int_types.asn1 
Failed to convert: ResolveError(FailedToResolveReference("18446744073709551615"))

The above definition compiles successfully with asn1c v0.9.29.

While I can leave this unconstrained as a work around, the ASN.1 spec allows for value ranges larger than those that can be represented in 64 bits. The maximum upper bound I'm able to use successfully with asn1rs appears to be equivalent to i64::MAX.

SIZE does not accept a Value Reference for the bounds

The asn1rs parser currently fails on this:

DRB-ToAddModList ::=				SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod

with this error:

Failed to load file /home/itk/itk/src/libitk/src/3gppasn1/asn1/rrc.asn: Model(At line 263, column 47 an unexpected range value was encountered: "maxDRB"

Looking at the source I can see it is expecting an integer literal there, but the ASN1 source I am trying to parse has a 'Value Reference' (ie a name referencing a value assigned elsewhere in the file).

X.680 says this:

The ASN.1 value assignment notation enables a name to be given to a value of a specified type. This name can be used
wherever a reference to that value is needed.

The name maxDRB is defined later in the ASN1 source file as:

maxDRB						INTEGER ::= 11

It is not clear to me how 'Value References' can be implemented, because the definition of the reference apparently doesn't come before the usage of it in the source file.

Integer RANGE with single value

This seems to be valid syntax but does not parse in asn1rs, yet (in contrast to SIZE for which this already works)

    BasicConstrainedFExtensible ::= SEQUENCE {
        abc INTEGER(8)
    }

    BasicConstrainedFExtensible ::= SEQUENCE {
        abc INTEGER(8,...)
    }

multiple patterns in `if let` and `while let` are unstable

  1. I am trying to use this tool to convert asn.1 to protobuf and running into the following error. I am not familiar with Rust; appreciate any help in resolving this.
⟫ cargo --version
cargo 1.32.0
⟫ rustc --version
rustc 1.32.0
⟫ cargo build
   Compiling asn1rs v0.1.12 (/home/cord/sd-ran/asn1rs)
error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215)
  --> src/model/rust.rs:51:9
   |
51 | /         if let RustType::Vec(inner) | RustType::Option(inner) = self {
52 | |             inner.into_inner_type()
53 | |         } else {
54 | |             self
55 | |         }
   | |_________^

error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215)
  --> src/model/rust.rs:62:9
   |
62 | /         if let RustType::Vec(inner) | RustType::Option(inner) = self {
63 | |             inner.to_inner()
64 | |         } else {
65 | |             None
66 | |         }
   | |_________^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
error: Could not compile `asn1rs`.

To learn more, run the command again with --verbose.

The above error is fixed with the following change (which is a revert of a previous commit):

diff --git a/src/model/rust.rs b/src/model/rust.rs
index bbdb091..15e3aef 100644
--- a/src/model/rust.rs
+++ b/src/model/rust.rs
@@ -48,10 +48,10 @@ impl RustType {
         if self.is_primitive() {
             return self;
         }
-        if let RustType::Vec(inner) | RustType::Option(inner) = self {
-            inner.into_inner_type()
-        } else {
-            self
+        match self.clone() {
+            RustType::Vec(inner) => inner.into_inner_type(),
+            RustType::Option(inner) => inner.into_inner_type(),
+            _ => self,
         }
     }

@@ -59,10 +59,10 @@ impl RustType {
         if self.is_primitive() {
             return Some(self.to_string());
         }
-        if let RustType::Vec(inner) | RustType::Option(inner) = self {
-            inner.to_inner()
-        } else {
-            None
+        match self {
+            RustType::Vec(inner) => inner.to_inner(),
+            RustType::Option(inner) => inner.to_inner(),
+            _ => None,
         }
     }
  1. The build then fails as follows:
⟫ cargo build
   Compiling asn1rs v0.1.12 (/home/cord/sd-ran/asn1rs)
error: assignments in const fn are unstable
  --> src/gen/sql.rs:97:9
   |
97 |         self.optimize_tables_for = None;
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: assignments in const fn are unstable
   --> src/gen/sql.rs:102:9
    |
102 |         self.primary_key_hint = Some(PrimaryKeyHint::WrapOnOverflow);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: assignments in const fn are unstable
   --> src/gen/sql.rs:107:9
    |
107 |         self.primary_key_hint = None;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

error: Could not compile `asn1rs`.

Above error was resolved with the following change but not sure if this is the right thing to do:

diff --git a/src/gen/sql.rs b/src/gen/sql.rs
index 1fd48db..ad968c3 100644
--- a/src/gen/sql.rs
+++ b/src/gen/sql.rs
@@ -93,17 +93,17 @@ impl SqlDefGenerator {
         self
     }

-    pub const fn no_table_write_optimization(mut self) -> Self {
+    pub fn no_table_write_optimization(mut self) -> Self {
         self.optimize_tables_for = None;
         self
     }

-    pub const fn wrap_primary_key_on_overflow(mut self) -> Self {
+    pub fn wrap_primary_key_on_overflow(mut self) -> Self {
         self.primary_key_hint = Some(PrimaryKeyHint::WrapOnOverflow);
         self
     }

-    pub const fn no_wrap_of_primary_key_on_overflow(mut self) -> Self {
+    pub fn no_wrap_of_primary_key_on_overflow(mut self) -> Self {
         self.primary_key_hint = None;
         self
     }




Build failure in model: `syn::Item` cannot be formatted using `{:?}`

With both the crates.io version and on master, I get the following build error:

error[E0277]: `syn::Item` doesn't implement `std::fmt::Debug`
   --> /home/alex/.cargo/git/checkouts/asn1rs-f6cc173094da5683/b189ef6/asn1rs-model/src/ast/mod.rs:117:40
    |
117 |         println!("Matching item {:?}", item);
    |                                        ^^^^ `syn::Item` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `std::fmt::Debug` is not implemented for `syn::Item`
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

I guess the problem is that if cfg! is a runtime gate, and the gated code still has to build. And maybe the fact that the build now uses syn v1.0.109. The Debug trait for syn's Item can be enabled with the extra-traits feature flag.

(P.S.: Great work with the decoder, I'm also using it to decode v1.4.1 CAMs :) It works well once I get it to build.)

DER Support

Hi.
My project heavily depends on parsing DER encoded data.
Your crate is by far the most interesting ASN1 parsers.
Is it hard to implement DER for it too?
I can contribute to that but I'm not sure where to start.

Global and hierarchical state

I love this rustic implementation of parser using TryFrom but it needs a global state e.g. to support IMPLICIT/EXPLICIT/AUTOMATIC TAGS that will affect all sub structures

Make protobuf optional

Hello.
I was trying to find a way to read uper data in my rust code and I could not find a way to do this using your project without importing protobuf.
I checked and found the solution.
If you could feature gate this line, one can read uper without having protobuf:

&ProtobufSerializer,

Thanks

Fix top level INTEGER support

Trying to compile this asn1 file fail

NGAP-CommonDataTypes {

itu-t (0) identified-organization (4) etsi (0) mobileDomain (0)

ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-CommonDataTypes (3) }

DEFINITIONS AUTOMATIC TAGS ::=

BEGIN

Criticality ::= ENUMERATED { reject, ignore, notify }

Presence ::= ENUMERATED { optional, conditional, mandatory }

PrivateIE-ID ::= CHOICE {

local INTEGER (0..65535),

global OBJECT IDENTIFIER

}

ProcedureCode ::= INTEGER (0..255)

ProtocolExtensionID ::= INTEGER (0..65535)

ProtocolIE-ID ::= INTEGER (0..65535)

TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome }

END

with this message

Failed to convert docs/clean/common.asn1, reason: Model(UnexpectedToken(   0: asn1rs::model::Model<asn1rs::model::Asn>::try_from
   1: asn1rs::converter::convert_to_rust
   2: asn1rs::main
   3: std::rt::lang_start::{{closure}}
   4: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
      std::panicking::try::do_call
             at src/libstd/panicking.rs:292
   5: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:78
   6: std::panicking::try
             at src/libstd/panicking.rs:270
      std::panic::catch_unwind
             at src/libstd/panic.rs:394
      std::rt::lang_start_internal
             at src/libstd/rt.rs:51
   7: main
   8: __libc_start_main
   9: _start
, Text("INTEGER")))

The nested integer works though

PrivateIE-ID ::= CHOICE {

local INTEGER (0..65535),

global OBJECT IDENTIFIER

}

OBJECT IDENTIFIER not supported

Hi,

[I'm quite new to asn1 (I only used it, but not written anything in it). Are there any good references or books to get into the asn1 topic?]

I've started to try asn1c against 3G/UMTS asn1 files (https://github.com/osmocom/osmo-iuh/tree/master/asn1)
It fails when parsing https://github.com/osmocom/osmo-iuh/blob/master/asn1/hnbap/HNBAP-CommonDataTypes.asn
with the following error.

I'm using asn1rs v0.2.2-25-gb6d5f77f6095 with rustc 1.56.1.

PrivateIE-ID    ::= CHOICE {
        local           INTEGER (0..65535),
        global          OBJECT IDENTIFIER
}
lynxis@rust:~/asn1rs$ ./target/debug/asn1rs /tmp/dest  /home/lynxis/asn-tests/osmo-iuh/hnbap/HNBAP-CommonDataTypes.asn 
Failed to load file /home/lynxis/asn-tests/osmo-iuh/hnbap/HNBAP-CommonDataTypes.asn: Model(At line 36, column 17 an unexpected token was encountered: "IDENTIFIER"
   0: <asn1rs_model::model::err::Error as core::convert::From<asn1rs_model::model::err::ErrorKind>>::from
             at asn1rs-model/src/model/err.rs:36:24
   1: <T as core::convert::Into<U>>::into
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/convert/mod.rs:540:9
   2: asn1rs_model::model::err::Error::unexpected_token
             at asn1rs-model/src/model/err.rs:93:9
   3: <asn1rs_model::model::choice::Choice<asn1rs_model::model::lor::Unresolved> as core::convert::TryFrom<&mut core::iter::adapters::peekable::Peekable<T>>>::try_from
             at asn1rs-model/src/model/choice.rs:93:13
   4: asn1rs_model::model::Model<asn1rs_model::model::asn::Asn<asn1rs_model::model::lor::Unresolved>>::read_definition
             at asn1rs-model/src/model/mod.rs:240:30
   5: asn1rs_model::model::Model<asn1rs_model::model::asn::Asn<asn1rs_model::model::lor::Unresolved>>::try_from
             at asn1rs-model/src/model/mod.rs:116:40
   6: asn1rs::converter::Converter::load_file
             at src/converter.rs:66:21
   7: asn1rs::main
             at src/main.rs:34:25
   8: core::ops::function::FnOnce::call_once
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:227:5
   9: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/sys_common/backtrace.rs:125:18
  10: std::rt::lang_start::{{closure}}
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/rt.rs:63:18
  11: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:259:13
      std::panicking::try::do_call
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:403:40
      std::panicking::try
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:367:19
      std::panic::catch_unwind
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panic.rs:129:14
      std::rt::lang_start_internal::{{closure}}
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/rt.rs:45:48
      std::panicking::try::do_call
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:403:40
      std::panicking::try
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:367:19
      std::panic::catch_unwind
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panic.rs:129:14
      std::rt::lang_start_internal
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/rt.rs:45:20
  12: std::rt::lang_start
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/rt.rs:62:5
  13: main
  14: __libc_start_main
  15: _start

)

IMPLICIT/EXPLICIT tags

I can see that you have implemented ITU-T X.680 | ISO/IEC 8824-1, G.2.12.3 here:

fn assign_implicit_tags(fields: &[Field]) -> Vec<Field> {

But can you please implement ITU-T X.680 | ISO/IEC 8824-1, G.2.12.5 too?
There is a good, simple explanation of it in let's encrypt docs.

I'm not sure how it should be after parsing. Now field.tag is of kind of Tag. Maybe it should be Explicitness<Tag>.

For PER/UPER, both are the same as current implementation, but for BER/DER, explicit fields are their own type wrapped with a ContextSpecific. So It parses input bytes differently.

Can you please take a look at it?
It is blocking #10.

Port asn1c X.509 and LDAPv3 examples

asn1c (https://github.com/vlm/asn1c) is arguably one of the most known and complete ASN.1 compilers. It has a few examples for common ASN.1 modules, such as X.509 and LDAPv3. If you compile asn1c from source with the examples, there's a script that generates the .asn1 files from the RFCs directly.

I pre-generated those for X.509 and LDAP3 and added them here for reference:
https://github.com/Devolutions/asn1rs/tree/examples/examples

For X.509, both the explicit and implicit modules are generated, I don't know which one is better.

I know the current readme says asn1rs won't work with most elaborate ASN.1 modules, but if there are complex ones it should support first, it should be X.509 and LDAPv3 :) I tried and both fail at this point, but I don't know enough of ASN.1 and asn1rs to see which part of the file is not handled correctly.

In all cases, it should be a good thing to include "clean" .asn1 files for useful specifications, known to work with asn1rs. With no_std support, imagine being able to a complete X.509 certificate parser and writer that works in WebAssembly, that would be amazing :)

SQL generator might needs to re-order declarations

itu-t(0) identified-organization(4) etsi(0) itsDomain(5) wg1(1) en(302637) cam(2) version(1) first declares ItsPduHeader - which uses StationID - and then declares StationID. The resulting SQL code looks something like this:

CREATE TABLE ItsPduHeader (
    id SERIAL PRIMARY KEY,
    protocol_version SMALLINT NOT NULL,
    message_id SMALLINT NOT NULL,
    station_id INTEGER REFERENCES StationID(id) ON DELETE CASCADE ON UPDATE CASCADE NOT NULL
);

CREATE INDEX ON ItsPduHeader(station_id);

CREATE TABLE StationID (
    id SERIAL PRIMARY KEY
);

This does not work, because while creating the ItsPduHeader the table for StationID does not yet exist and can therefore not be referenced.

The following code is not supported

MessageFrameExt ::= SEQUENCE {
messageId MESSAGE-ID-AND-TYPE.&id({MessageTypes}),
value MESSAGE-ID-AND-TYPE.&Type({MessageTypes}{@.messageId}),
...
}

MESSAGE-ID-AND-TYPE ::= CLASS {
	&id ExtMsgID UNIQUE,
	&Type
} WITH SYNTAX {&Type IDENTIFIED BY &id}

MessageTypes MESSAGE-ID-AND-TYPE ::= {
	{ TestMsg IDENTIFIED BY testData } |	
	{ RTCMcorrections IDENTIFIED BY rtcmData } |
	{ PAMData IDENTIFIED BY pamData } |
	{ CLPMM IDENTIFIED BY clpmmData } |
	{ PersonalSafetyMessage IDENTIFIED BY psmData } |
	{ RoadsideCoordination IDENTIFIED BY rscData } |
	{ SensorSharingMsg IDENTIFIED BY ssmData } |
	{ VehIntentionAndRequest IDENTIFIED BY virData } |
	{ VehiclePaymentMessage IDENTIFIED BY vpmData },
	...
}

ExtMsgID ::= INTEGER (0..32767) 

-- Test Message
testData ExtMsgID ::= 0

-- DAY II Messages *********************
rtcmData ExtMsgID ::= 10
rscData ExtMsgID ::= 11
ssmData ExtMsgID ::= 12
virData ExtMsgID ::= 13
pamData ExtMsgID ::= 14
psmData ExtMsgID ::= 15
clpmmData ExtMsgID ::= 16
vpmData ExtMsgID ::= 17

Automatically assigned tags might be wrong

SET requires that the fields are sorted by tag canonically. For implicit tags, the tag must be determined to sort the fields (AsnDefWriter::sort_fields_canonically).
The tags are resolved from the type (RustType::type_tag) which has no way to figure out the tag for RustType::Complex because the inner type is represented lazily as String. The current implementation just returns a constant value here, but actually this would require a recursive call as for RustType::Option. The infrastructure for this - resolving types across multiple asn-module definitions - isn't there at all at the moment.

Also: there is currently no error check for duplicate tags

Solve character string types in a nicer way

Currently each character string type has its own read_*/write_* fn which every Reader/Writer must implement

    fn read_utf8string<C: utf8string::Constraint>(&mut self) -> Result<String, Self::Error>;

    fn read_ia5string<C: ia5string::Constraint>(&mut self) -> Result<String, Self::Error>;

    fn read_numeric_string<C: numericstring::Constraint>(&mut self) -> Result<String, Self::Error>;

    fn read_visible_string<C: visiblestring::Constraint>(&mut self) -> Result<String, Self::Error>;

    fn read_printable_string<C: printablestring::Constraint>(
        &mut self,
    ) -> Result<String, Self::Error>;

Consider a common fn (like read_characters?) and pass the Charset as (type) parameter? Same with the Utf8String, Ia5String, ... types.

Further encoding support

Issue Tracking Issue for tracking the progress of further encoding implementation.

Preconditions:

  • (in progress, clean-up) Refactor to provide better extensibility (see 325c96f and asn1rs::syn)

Potential encodings:

  • DER #10
  • PER
  • uPER
  • XER #1

asn1rs chokes on empty SEQUENCE

I was attempting to use asn1rs to produce a rust codec for the 3GPP RRC protocol (38.331. It immediately bombs out with this error:

Failed to load file rrc.asn: Model(At line 36, column 34 expected text, but instead got: '}'
   0: <asn1rs_model::model::ComponentTypeList as core::convert::TryFrom<&mut core::iter::adapters::Peekable<alloc::vec::IntoIter<asn1rs_model::parser::Token>>>>::try_from
   1: asn1rs_model::model::Model<asn1rs_model::model::Asn>::read_sequence_or_sequence_of
   2: asn1rs_model::model::Model<asn1rs_model::model::Asn>::read_role_given_text
   3: <asn1rs_model::model::Choice as core::convert::TryFrom<&mut core::iter::adapters::Peekable<alloc::vec::IntoIter<asn1rs_model::parser::Token>>>>::try_from
   4: asn1rs_model::model::Model<asn1rs_model::model::Asn>::try_from
   5: asn1rs::converter::Converter::load_file
   6: asn1rs::main
   7: std::sys_common::backtrace::__rust_begin_short_backtrace
   8: std::rt::lang_start::{{closure}}
   9: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/ops/function.rs:259:13
      std::panicking::try::do_call
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:381:40
      std::panicking::try
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:345:19
      std::panic::catch_unwind
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panic.rs:396:14
      std::rt::lang_start_internal
             at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/rt.rs:51:25
  10: main
  11: __libc_start_main
  12: <unknown>

)

It is complaining about the field messageClassExtension field below:

BCCH-DL-SCH-MessageType ::= CHOICE {
	c1						CHOICE {
		systemInformation						SystemInformation,
		systemInformationBlockType1				SystemInformationBlockType1
	},
	messageClassExtension	SEQUENCE {}
}

I'm not sure why they have these empty SEQEUNCE fields, presumably something to do with extensibility.

I was using asn1rs 0.2.0.

trivial: Build Error

When trying to run cargo build following build error is observed.

$ cargo build
   Compiling asn1rs-model v0.2.2 (/home/gabhijit/Work/hyphenOs/asn1rs/asn1rs-model)
error[E0599]: no method named `value` found for struct `LitBool` in the current scope
   --> asn1rs-model/src/ast/attribute.rs:194:78
    |
194 | ...                   syn::Lit::Bool(val) => LiteralValue::Boolean(val.value()),
    |                                                                        ^^^^^-- help: remove the arguments
    |                                                                        |
    |                                                                        field, not a method

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `asn1rs-model`

To learn more, run the command again with --verbose.

The fix is trivial, will send a PR.

Extensible SEQUENCE causes errors during serialization

Compiling the following asn1 which defines an extensible SEQUENCE:

TestTypes DEFINITIONS AUTOMATIC TAGS ::= BEGIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
  MySequence ::= SEQUENCE {                                                                                                                                                                                                                                    
    val1 INTEGER,                                                                                                                                                                                                                                              
    val2 INTEGER,                                                                                                                                                                                                                                              
    ...                                                                                                                                                                                                                                                        
  }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
END

with asn1rs works (also compiles with asn1c), however, when using the generated rust bindings, it panics in asn1rs source. For example, using the above definition in a serialization test like so:

extern crate asn1rs_test;                                                                                                                                                                                                                                    
extern crate asn1rs;                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                               
use asn1rs_test::test_types::*;                                                                                                                                                                                                                              
use asn1rs::prelude::*;                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                               
fn main()                                                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                                              
    let my_sequence = MySequence{[ ]                                                                                                                                                                                                                           
        val1: 1020,                                                                                                                                                                                                                                            
        val2: 1080                                                                                                                                                                                                                                             
    };                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                               
    let mut writer = UperWriter::default();                                                                                                                                                                                                                    
    writer.write(&my_sequence).unwrap();                                                                                                                                                                                                                       
    let mut reader = writer.as_reader();                                                                                                                                                                                                                       
    let deser = reader.read::<MySequence>().unwrap();                                                                                                                                                                                                          
    assert_eq!(my_sequence, deser);                                                                                                                                                                                                                            
}

Fails with

---- serde_mysequence stdout ----
thread 'main' panicked at 'assertion failed: scope.unwrap().exhausted()', /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/asn1rs-0.2.2/src/syn/io/uper.rs:224:9

Code refactoring before larger contributions

Hey,

this project seems great and good base for wider implementations.
I need Rust ASN.1 type generator to support few additional ITS standards, including

It also required (C)OER encoding. There was some talk about it here, but I guess it was not finished.

I am planning to extend the project to fulfill at least some of these requirements, and let's see where I get.

What do you think should be good starting point from refactoring the code? There are some mentions in TODO section, and I think that some refactoring might be good if another encoding/decoding type will be added.

Drastically reduce the public API surface

Should the API surface be drastically reduced to prevent what would be considered breaking changes? Current a lot of types and fns are pub and thus would not be allowed to change after 1.0.0 release

Tracking Issue: Value References

ValueReferences are the constants of ASN.1. With this PR constant definitions in ASN.1 are parsed.

  • Parse and resolve basic Value References (Integers) #49
  • Add constant values to rust (75f235b)
  • Support ENUMERATED values (0c1cd81)
  • Properly parse hex values and other non-integer VRs
  • an (yet) unsupported value reference literal of type 'TypeReference("...", None)' was discovered: "0" (simple values wrapped in tuples are not supported yet)

PR #49 changes public API and thus is a breaking change in this regard. A version bump to 0.3.0 is therefore required by the semantic versioning guidelines No. 4: "Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable."

This resolves #45

SQL duplicate table for inner structures

Hi,
I tried to convert a LTE RRC ASN1 spec to PSQL.
The ASN1 definition contains inner/nested structures such as ENUMERATED with the same name multiple times.
Example ASN1 spec (https://github.com/proj3rd/3gpp-specs/blob/master/36-series/36331/36331-f01.asn1#L2152-L2166):

SystemInformationBlockType1-v1320-IEs ::=	SEQUENCE {
	freqHoppingParametersDL-r13				SEQUENCE {
		mpdcch-pdsch-HoppingNB-r13				ENUMERATED {nb2, nb4}		OPTIONAL,	 -- Need OR
		interval-DLHoppingConfigCommonModeA-r13	CHOICE {
			interval-FDD-r13					ENUMERATED {int1, int2, int4, int8},
			interval-TDD-r13					ENUMERATED {int1, int5, int10, int20}
		}																	OPTIONAL,	 -- Need OR
		interval-DLHoppingConfigCommonModeB-r13	CHOICE {
			interval-FDD-r13					ENUMERATED {int2, int4, int8, int16},
			interval-TDD-r13					ENUMERATED { int5, int10, int20, int40}
		}																	OPTIONAL,	 -- Need OR
		mpdcch-pdsch-HoppingOffset-r13			INTEGER (1..maxAvailNarrowBands-r13)	OPTIONAL	 -- Need OR
	}																OPTIONAL,	 -- Cond Hopping
	nonCriticalExtension						SystemInformationBlockType1-v1350-IEs					OPTIONAL
}

Resulting SQL definition via asn1rs . ./spec.asn1 --convert-to sql:

CREATE TABLE IntervalFddR13IntervalFddR13 (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);
INSERT INTO IntervalFddR13IntervalFddR13 (id, name) VALUES
    (0, 'Int1'), 
    (1, 'Int2'), 
    (2, 'Int4'), 
    (3, 'Int8');

/* ... */

CREATE TABLE IntervalFddR13IntervalFddR13 (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);
INSERT INTO IntervalFddR13IntervalFddR13 (id, name) VALUES
    (0, 'Int2'), 
    (1, 'Int4'), 
    (2, 'Int8'), 
    (3, 'Int16');

Both interval-FDD-r13 ENUMERATED for instance are converted to a IntervalFddR13IntervalFddR13 SQL table.
The second CREATE TABLE statement fails because the table already exists.

I am using the latest asn1rs master build (https://github.com/kellerkindt/asn1rs/tree/68afe21e68b8138414d3dec1f706bd5a7e86a95d)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.