Initial situation
Currently, I am trying to iterate through a complex ASN.1 sequence using the AsnReader class. Most code snippets down below are inspired by a well hidden ASN.1 BER/CER/DER Reader & Writer design document.
The ASN.1 sequence is defined as type of envelopedData
, which can be identified with the OID 1.2.840.113549.1.7.3
. Here you can see the visualized ASN.1 type definition. The sequence itself is DER (Distinguished Encoding Rules) encoded.
First, I tried to instantiate a new AsnReader with DER as encoding rules.
var bytes = File.ReadAllBytes(@"pathToMyFile.txt");
var reader = new AsnReader(fileBytes, AsnEncodingRules.DER);
var sequence = reader.ReadSequence();
It ended up in this exception.
System.Formats.Asn1.AsnContentException: "The encoded length is not valid under the requested encoding rules, the value may be valid under the BER encoding."
Question: Why can't I set the encoding rules to DER? Does it make any difference to use BER?
For now I set the encoding rules to BER, which worked fine until...
var reader = new AsnReader(fileBytes, AsnEncodingRules.BER);
var sequence = reader.ReadSequence();
var context = new Asn1Tag(TagClass.ContextSpecific, 0);
var next_sequence = sequence.ReadSequence(context);
The above ended up in this exception:
System.Formats.Asn1.AsnContentException: "The provided data is tagged with 'Universal' class value '6', but it should have been 'ContextSpecific' class value '0'."
Question: Does anybody knows how I could iterate through this ASN.1 sequence using the AsnReader class?
I highly appreciate any kind of help, cheers!
Edit 1: AsnReader
After some research I finally managed to read the documentation for the AsnReader class properly. The documentation describes the class as...
... a stateful, forward-only reader for BER-, CER-, or DER-encoded ASN.1 data.
That's why my initial AsnReader implementation is total nonsense.
In the following I would like to give a small example of how to iterate through the individual sequences or data fields in a complex ASN.1 structure using AsnReader.
var bytes = new ReadOnlyMemory<byte>(File.ReadAllBytes(@"pathToMyFile.txt"));
var reader = new AsnReader(fileBytes, AsnEncodingRules.BER);
var sequence = reader.ReadSequence();
reader.ThrowIfNotEmpty();
var oid = sequence.ReadObjectIdentifier();
Console.WriteLine(oid);
var context = new Asn1Tag(TagClass.ContextSpecific, 0);
if (sequence.HasData && sequence.PeekTag().HasSameClassAndValue(context))
{
var contextSequence = sequence.ReadSequence(context);
var subSequence = contextSequence.ReadSequence();
var version = subSequence.ReadInteger();
Console.WriteLine(version);
}
The above code returns the correct values as follows.
>> 1.2.840.113549.1.7.3
>> 0
Nevertheless, I still don't know why I can't set the encoding rules to DER.
Question: The decoding process right now is quite elaborate, since it's a stateful, forward-only reader. Is there any way to reach specific data fields faster?
Data to test with: This is a base 64 encoded string of type envelopedData
, which can be identified with the details provided at the top of the question.
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