Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error parsing ParsableOctetString while parsing EncapsulatedContentInfo (test case) #283

Open
ornati opened this issue Oct 8, 2024 · 6 comments

Comments

@ornati
Copy link

ornati commented Oct 8, 2024

Hello,

I have troubles parsing a "timestamp".. I don't have access to the code that produced it.

Code to reproduce the issue:

from asn1crypto.cms import EncapsulatedContentInfo

ENC_CONTENT_INFO_FILE = 'enc_content_info2.dat'
cnt = EncapsulatedContentInfo.load(open(ENC_CONTENT_INFO_FILE, 'rb').read())
cnt.native

enc_content_info2.dat.zip

Error with last git version b763a75 (it's the same with v1.5.1):

Traceback (most recent call last):
  File "/home/paolo/src/asn1crypto/crashtest.py", line 6, in <module>
    cnt.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4070, in native
    self._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4014, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 3986, in _parse_children
    child = _build(*child)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5539, in _build
    value = _build(*info, spec=spec, spec_params={'no_explicit': True})
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5581, in _build
    raise ValueError(unwrap(
ValueError: Error parsing asn1crypto.core.ParsableOctetString - method should have been primitive, but constructed was found
    while parsing asn1crypto.cms.EncapsulatedContentInfo

Side note, openssl asn1parse works:

openssl asn1parse -inform DER -in enc_content_info2.dat
@jinhua115
Copy link

jinhua115 commented Oct 8, 2024 via email

@joernheissler
Copy link
Collaborator

You need to use asn1crypto.cms.ContentInfo.

@ornati
Copy link
Author

ornati commented Oct 8, 2024

Thanks!

However this test case was part of a bigger issue, this one:

from asn1crypto.cms import ContentInfo
import asn1crypto.tsp  # extends ContentInfo

INPUT_FILE = 'problematic.xml.p7m.tsd'

cnt = ContentInfo.load(open(INPUT_FILE, 'rb').read(), strict=True)
cnt.native

Error:

Traceback (most recent call last):
  File "/home/paolo/src/asn1crypto/crashtest2.py", line 8, in <module>
    cnt.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4086, in native
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4081, in native
    self._native[name] = child.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4086, in native
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4081, in native
    self._native[name] = child.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 1249, in native
    return self.chosen.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4555, in native
    self._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4527, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4521, in _parse_children
    child._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4014, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 3988, in _parse_children
    child._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4014, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 3986, in _parse_children
    child = _build(*child)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5539, in _build
    value = _build(*info, spec=spec, spec_params={'no_explicit': True})
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5581, in _build
    raise ValueError(unwrap(
ValueError: Error parsing asn1crypto.core.ParsableOctetString - method should have been primitive, but constructed was found
    while parsing asn1crypto.cms.EncapsulatedContentInfo
    while parsing asn1crypto.tsp.TimeStampAndCRL
    while parsing asn1crypto.tsp.TimeStampTokenEvidence
    while parsing asn1crypto.tsp.TimeStampedData
    while parsing asn1crypto.cms.ContentInfo

"problematic.xml.p7m.tsd" is a PKCS#7 with a timestamp applied.

Am I doing something wrong again? ;-)

If not I'll open another issue with "problematic.xml.p7m.tsd" attached.

@joernheissler
Copy link
Collaborator

I don't know if you're doing something wrong. If you could generate a minimal example (i.e. not a full PKCS#7 file) it would help a lot.

@ornati
Copy link
Author

ornati commented Oct 9, 2024

I managed to reproduce the problem with just the timestamp part applied to a simple TXT file.

I have:

  • test.txt (4 ASCII bytes: "test")
  • test.txt.tsd (4376 bytes)
  • the Python code to produce "test.txt.tsd" using asn1crypto (it calls an external SOAP service to get the actual timestamp)

I don't know how to get more minimal than this ;-)

cnt = ContentInfo.load(...)
cnt.value

results in

Traceback (most recent call last):
  File "/home/paolo/src/asn1crypto/crashtest3.py", line 7, in <module>
    cnt.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4086, in native
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4081, in native
    self._native[name] = child.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4086, in native
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4081, in native
    self._native[name] = child.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 1249, in native
    return self.chosen.native
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4555, in native
    self._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4527, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4521, in _parse_children
    child._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4014, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 3988, in _parse_children
    child._parse_children(recurse=True)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 4014, in _parse_children
    raise e
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 3986, in _parse_children
    child = _build(*child)
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5539, in _build
    value = _build(*info, spec=spec, spec_params={'no_explicit': True})
  File "/home/paolo/src/asn1crypto/asn1crypto/core.py", line 5581, in _build
    raise ValueError(unwrap(
ValueError: Error parsing asn1crypto.core.ParsableOctetString - method should have been primitive, but constructed was found
    while parsing asn1crypto.cms.EncapsulatedContentInfo
    while parsing asn1crypto.tsp.TimeStampAndCRL
    while parsing asn1crypto.tsp.TimeStampTokenEvidence
    while parsing asn1crypto.tsp.TimeStampedData
    while parsing asn1crypto.cms.ContentInfo

I'm attaching everything here, but maybe I should open another issue?
parsing-err-testcase.zip

@joernheissler joernheissler reopened this Oct 9, 2024
@joernheissler
Copy link
Collaborator

This might be a bug in asn1crypto.

diff --git a/asn1crypto/tsp.py b/asn1crypto/tsp.py
index f006da9..ead07cc 100644
--- a/asn1crypto/tsp.py
+++ b/asn1crypto/tsp.py
@@ -171,7 +171,7 @@ class MetaData(Sequence):
 
 class TimeStampAndCRL(Sequence):
     _fields = [
-        ('time_stamp', EncapsulatedContentInfo),
+        ('time_stamp', ContentInfo),
         ('crl', CertificateList, {'optional': True}),
     ]

@wbond Do you remember why this is an EncapsulatedContentInfo?
All test cases succeed with and without above patch.

RFC5544 defines:

TimeStampAndCRL ::= SEQUENCE {
   timeStamp   TimeStampToken,          -- according to RFC 3161
   crl         CertificateList OPTIONAL -- according to RFC 5280
}

And RFC3161 defines:

A TimeStampToken is as follows.  It is defined as a ContentInfo
([CMS]) and SHALL encapsulate a signed data content type.

TimeStampToken ::= ContentInfo
  -- contentType is id-signedData ([CMS])
  -- content is SignedData ([CMS])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants