root_options not available for octet string
Environment
- [x] Ruby version: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
- [x] rasn1 version: Custom Branch: c41fea550b3d83f40039dba2604035850366c764
Description
Context
I am trying to implement the LDAP DelRequest specification:
4.8. Delete Operation
DelRequest ::= [APPLICATION 10] LDAPDNhttps://www.rfc-editor.org/rfc/rfc4511#section-4.8
Example:
MCwCAQJKJ3VpZD1iamVuc2VuLG91PVBlb3BsZSxkYz1leGFtcGxlLGRjPWNvbQ==
Parsed: https://lapo.it/asn1js/#MCwCAQJKJ3VpZD1iamVuc2VuLG91PVBlb3BsZSxkYz1leGFtcGxlLGRjPWNvbQ
Wireshark:
Csharp approach: https://github.com/microsoft/WindowsProtocolTestSuites/blob/061e708767b42dfc085356c190f34ee3788f1180/ProtoSDK/MS-ADTS-LDAP/AdtsLdapV2Asn1Codec/DelRequest.cs
What I've tried
I have tried implementing it with rasn1 in various ways:
- Try to use
root_options
RASN1::Types.define_type('LdapString', from: RASN1::Types::OctetString, in_module: self)
RASN1::Types.define_type('LdapDN', from: LdapString, in_module: self)
class DelRequest < LdapDN
root_options name: 'DelRequest',
class: :application,
implicit: 10
end
# Usage:
class ProtocolOp < LdapModel
choice model_name,
content: [
model(:del_request, DelRequest),
]
end
But this approach above gives the following error:
undefined method `root_options' for class Ldap::DelRequest
- Trying to use the
wrapperapproach - but this approach is further away from the original ASN1 specification, and doesn't seem to work either (potentially pebkac):
RASN1::Types.define_type('LdapString', from: RASN1::Types::OctetString, in_module: self)
RASN1::Types.define_type('LdapDN', from: LdapString, in_module: self)
class DelRequest < LdapDN
end
# Usage:
class ProtocolOp < LdapModel
choice model_name,
content: [
wrapper(model(:del_request, DelRequest), implicit: 10, class: :application),
]
end
test failure:
CHOICE protocol_op: no type matching "J'uid=bjensen,ou=People,dc=example,dc=com"
Expected behavior
Parsed successfully:
{
LdapMessage: {
message_id: 2,
protocol_op: {
del_request: "euid=bjensen,ou=People,dc=example,dc=com"
}
}
Actual behavior
For attempt 1 - root_options API is not available for the defined type approach - but it is available for models
For attempt 2 - The parsing does not work, potentially pebkac
Suggested fix
Potentially this is a feature request to add root_options to defined types, or there's a maybe in a bug in the wrapper around a OctetString
Code to reproduce
https://github.com/adfoster-r7/rasn1/blob/4671183d66a91617f62cb6f75a84f5b6b9d58542/spec/ldap_spec.rb#L199-L212
Failure:
1) Ldap Ldap::LdapMessage when a DelRequest is parsed #parse parses the data successfully
Failure/Error: raise ASN1Error, "CHOICE #{@name}: no type matching #{der.inspect}" unless optional?
RASN1::ASN1Error:
CHOICE protocol_op: no type matching "J'uid=bjensen,ou=People,dc=example,dc=com"
#root_option is a Model method, so it cannot be used on base types.
To handle your case, you should define a model embdedding a single octet string:
class DelRequest < RASN1::Model
octet_string :DelRequest, implicit: 10, class: :application # ldap_dn should work too
end
Then, you can use this model in ProtocolOp:
class ProtocolOp < LdapModel
choice model_name,
content: [
model(:del_request, DelRequest),
]
end