I need to build an ASN.1 DER sequence for my digitial signature. The sequence is described in the following. My problem is the inner sequences, like encapContentInfo
, since I don't know how to add those inner sequences in my SignedData
sequence.
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos }
where
EncapsulatedContentInfo ::= SEQUENCE {
eContentType ContentType,
eContent [0] EXPLICIT OCTET STRING OPTIONAL }
Right now, I am writing the ASN.1 like this:
var writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
writer.WriteInteger(1, new Asn1Tag(TagClass.ContextSpecific, 0));
writer.WriteObjectIdentifier("2.16.840.1.101.3.4.2.1", new Asn1Tag(TagClass.ContextSpecific, 1));
// How do I add the inner sequence of type `encapContentInfo` here?
}
var extension = new X509Extension("1.2.840.113549.1.7.2", writer.Encode(), critical: false);
My guess would be to write the inner sequence first and then write it to the outer sequence. Nevertheless, I don't know if this is the correct way and how to implement it exactly.
So my question is: "Does anybody know how I could write this complex sequence?". I highly appreciate any kind of help or suggestion, cheers!
My first intention was right. I first have to write and encode the inner sequence and add the value to the outer sequence, like shown below.
public void CreateSequenceOfTypeSignedData()
{
var writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
writer.WriteInteger(1);
writer.WriteObjectIdentifier("2.16.840.1.101.3.4.2.1");
writer.WriteEncodedValue(CreateSequenceOfTypeEncapContentInfo());
}
var value = writer.Encode();
Console.WriteLine(Convert.ToBase64String(value));
}
public byte[] CreateSequenceOfTypeEncapContentInfo()
{
var writer = new AsnWriter(AsnEncodingRules.DER);
using (writer.PushSequence())
{
writer.WriteObjectIdentifier("1.2.840.113549.1.7.1");
}
return writer.Encode();
}
The above returns the following base64 string...
MBsCAQEGCWCGSAFlAwQCATALBgkqhkiG9w0BBwE=
... which can be decoded into the following using this online ASN.1 JavaScript decoder.