System.Security.Cryptography.CryptographicException: ASN1 unexpected end of data

Matt East 21 Reputation points
2022-04-20T18:17:24.403+00:00

Hello! I'm troubleshooting an issue where the following exception is occasionally being thrown while validating the signature of an AS2 message:

*System.Security.Cryptography.CryptographicException: ASN1 unexpected end of data.

StackTrace:
at System.Security.Cryptography.Pkcs.SignedCms.OpenToDecode(Byte[] encodedMessage, ContentInfo contentInfo, Boolean detached)
at System.Security.Cryptography.Pkcs.SignedCms.Decode(Byte[] encodedMessage)*

Most of the time AS2 messages are processed successfully. However, there doesn't appear to be any indication of why the exception is occasionally encountered. The general codeflow for my validation function is:

  • Get the message content in string form by piecing apart the received AS2 message
  • Get a byte[] of the message content string by calling Encoding.GetBytes using an "ISO-8859-1" encoding
  • Get the signature in string form by piecing apart the received AS2 message
  • Get a byte[] of the signature by calling Encoding.GetBytes using an "ISO-8859-1" encoding (the "Content-Transfer-Encoding" piece of the message is "binary")
  • Create a ContentInfo object using the message content byte[]
  • Create a SignedCms object using the ContentInfo object mentioned above and using the detached state (i.e. SignedCms(contentInfo, true))
  • Calling .Decode on the SignedCms object with the signature byte[] as the argument (i.e. signedCms.Decode(signature byte[])) which occasionally throws the exception

However, I'm stuck at the cause of the exception. Here are the steps I've taken so far:

  • Compared the signature in string form between a working case and an exception case. In both, they appear to be the same. I was hoping that the signatures might be different which could explain why .Decode is throwing the exception.
  • Investigated the certificates associated with the SignedCms object by looking at its .SignerInfos property. In at least the exception case, there are no SignerInfo objects in the SignedCms object's SignerInfos property. I was hoping that there might be a particular certificate which could be identified as the problem but was surprised that no certificates were found in SignerInfos.

Would you have advice on the best next steps to investigate the cause of the "ASN1 unexpected end of data" exception? Thanks so much!

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,254 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,238 questions
{count} votes

Accepted answer
  1. Fei Xue - MSFT 1,111 Reputation points
    2022-04-25T07:43:24.083+00:00

    @Matt East For the error message about 'System.Security.Cryptography.CryptographicException: ASN1 unexpected end of data', it indicates that the decode message was corrupt. You should add the logs to monitor the raw message and the message trying to decode, and investigate why it was modified.

    Here is a quick test to repro this issue:

     internal class TestSignedCms  
        {  
            string oringalMessage="Hello World!";  
            byte[] encodedMessage;  
            byte[] encodedMessage2;  
            SignedCms signedCms;  
      
            public TestSignedCms()  
            {  
      
                var cert = new X509Certificate2(@"C:\testCert.pfx", "password");       
                var cmsSigner = new CmsSigner(cert);  
      
                var msg = UTF8Encoding.Unicode.GetBytes(oringalMessage);  
                var contentInfo = new ContentInfo(msg);  
      
                signedCms = new SignedCms(contentInfo);  
                signedCms.ComputeSignature(cmsSigner);  
      
                encodedMessage=signedCms.Encode();  
      
                encodedMessage2 = new byte[encodedMessage.Length];  
                encodedMessage.CopyTo(encodedMessage2,0);  
                Array.Resize(ref encodedMessage2,encodedMessage.Length-1);  
      
            }  
            public void Run()  
            {  
                // Create a new, nondetached SignedCms message.  
                SignedCms signedCms = new SignedCms();  
      
                // encodedMessage is the encoded message received from  
                // the sender.  
                signedCms.Decode(encodedMessage2);  
                Console.WriteLine(UTF8Encoding.UTF8.GetString( signedCms.ContentInfo.Content));  
                // Verify the signature without validating the  
                // certificate.  
                signedCms.CheckSignature(true);  
                Console.ReadLine();  
            }  
        }  
    

1 additional answer

Sort by: Most helpful
  1. Matt East 21 Reputation points
    2022-08-15T13:36:14.337+00:00

    Following up on what appears to be the root cause of the issue: The code in question was intentionally removing new line characters (<13><10> character sequence) from the AS2 signature portion of the message to handle cases where a signature encoded in base64 was communicated over multiple lines. While this is appropriate to do for base64-encoded signatures, it's not appropriate to do for binary-encoded signatures. A binary-encoded signature that happened to have a <13><10> character sequence would incorrectly have that sequence removed and mangle the signature. Adding a check to only remove new line characters for base64-encoded signatures appears to have resolved the exception.

    0 comments No comments