Mimekit - Unable to cast object of type 'Org.BouncyCastle.Asn1.DerApplicationSpecific' to type 'Org.BouncyCastle.Asn1.Asn1SequenceParser'

Viewed 129

I'm working with mimekit to encrypt and decrypt mime messages and I'm encountering this error everytime I try to decrypt a message:

Unexpected object reading content. BouncyCastle.Crypto at Org.BouncyCastle.Cms.CmsContentInfoParser..ctor(Stream data) in //crypto/src/cms/CMSContentInfoParser.cs:line 35 at Org.BouncyCastle.Cms.CmsEnvelopedDataParser..ctor(Stream envelopedData) in //crypto/src/cms/CMSEnvelopedDataParser.cs:line 65 at MimeKit.Cryptography.BouncyCastleSecureMimeContext.d__50.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at PasarelaLibrary.Bases.GraphService.BaseGraphPasarela.d__11.MoveNext() in C:\Dev\Euroval\PasarelaAceuro\PasarelaLibrary\Bases\GraphService\BaseGraphPasarela.cs:line 302 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at PasarelaLibrary.Bases.GraphService.BaseGraphPasarela.d__9.MoveNext() in C:\Dev\Euroval\PasarelaAceuro\PasarelaLibrary\Bases\GraphService\BaseGraphPasarela.cs:line 237

Inner exception

Unable to cast object of type 'Org.BouncyCastle.Asn1.DerApplicationSpecific' to type 'Org.BouncyCastle.Asn1.Asn1SequenceParser'. at Org.BouncyCastle.Cms.CmsContentInfoParser..ctor(Stream data) in /_/crypto/src/cms/CMSContentInfoParser.cs:line 27

the problem is I'm just trying to encrypt and decrypt a message to test the library and the flow of the application and I'm getting this error. Above you can find the code I'm using. I'm using a x509Certificate with a password that I'm importing in the TemporarySecureMimeContext.

using var context = new TemporarySecureMimeContext();
await context.ImportAsync(certificate);
var encryptedMessage = await GetEncryptedMessage(context, stream, fileroute, certificate, mailFrom, mailTo);
using var testencrypted = new MemoryStream();
await encryptedMessage.WriteToAsync(testencrypted);
testencrypted.Position = 0;
var dec = await context.DecryptAsync(testencrypted); //here it explodes :(

public static async Task<MimeMessage> GetEncryptedMessage(TemporarySecureMimeContext context, Stream stream, string subject, X509Certificate certificate, string mailFrom, string mailTo)
{
    stream.Position = 0;
    SecureMailboxAddress mailFromEncrypted = new SecureMailboxAddress("name", mailFrom, certificate.GetFingerprint());
    SecureMailboxAddress mailToEncrypted = new SecureMailboxAddress("name", mailTo, certificate.GetFingerprint());
    BodyBuilder bodyBuilder = new BodyBuilder();
    using StreamReader reader = new StreamReader(stream);
    bodyBuilder.TextBody = await reader.ReadToEndAsync();
    MimeMessage message = new MimeMessage(new List<InternetAddress> { mailFromEncrypted }, new List<InternetAddress> { mailToEncrypted }, subject, bodyBuilder.ToMessageBody());
    message.Date = DateTime.Now;
    message.MessageId = MimeUtils.GenerateMessageId();
    await message.EncryptAsync(context);
    return message;
}

I already read other posts here and in other forums but nothing worked for this case scenario. Could someone help me with this?

1 Answers

You're using it wrong :-)

You are trying to decrypt a MIME message stream. You can't do that.

The SecureMimeContext.Decrypt() and DecryptAsync() methods expect the encrypted content of the MIME message.

If your goal is to load the MimeMessage and decrypt it, you would change your code to this:

using var context = new TemporarySecureMimeContext();
await context.ImportAsync(certificate);

// get an encrypted message
var encryptedMessage = await GetEncryptedMessage(context, stream, fileroute, certificate, mailFrom, mailTo);

// write the encrypted message to a stream
using var testencrypted = new MemoryStream();
await encryptedMessage.WriteToAsync(testencrypted);
testencrypted.Position = 0;

// load the message from the stream
var loadedMessage = await MimeMessage.LoadAsync(testencrypted);

// get the encrypted body
var encryptedBody = (ApplicationPkcs7Mime) loadedMessage.Body;

// decrypt it
var decryptedBody = await encryptedBody.DecryptAsync(context);

// restore the message to the pre-encrypted state
loadedMessage.Body = decryptedBody;
Related