wbond / asn1crypto

Python ASN.1 library with a focus on performance and a pythonic API
MIT License
335 stars 140 forks source link

Error parsing valid EncryptedContentInfo #264

Open natzlob opened 1 year ago

natzlob commented 1 year ago

I receive valid CMS EncryptedContentInfo bytes, which I call encrypted_content_info. From the EncryptedContentInfo, I can get the encrypted algorithm with encrypted_content_info['content_encryption_algorithm']. However, there is an error when extracting the EncryptedContent from encrypted_content_info. The error is:

encrypted_content_bytes = encrypted_content_info['encrypted_content']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../python3.7/site-packages/asn1crypto/core.py", line 3536, in __getitem__
    raise e
  File ".../python3.7/site-packages/asn1crypto/core.py", line 3531, in __getitem__
    return self._lazy_child(key)
  File ".../python3.7/site-packages/asn1crypto/core.py", line 3478, in _lazy_child
    child = self.children[index] = _build(*child)
  File ".../python3.7/site-packages/asn1crypto/core.py", line 5561, in _build
    METHOD_NUM_TO_NAME_MAP.get(method, method)
ValueError: Error parsing asn1crypto.core.OctetString - method should have been primitive, but constructed was found
    while parsing asn1crypto.cms.EncryptedContentInfo

When I take the EncryptedContentInfo, write it to file and use openssl asn1parse to parse it as follows: openssl asn1parse -inform der -in encrypted_content_info.ber, the encrypted content can be successfully extracted. If I take the encrypted content obtained from openssl asn1parse, I can then decrypt it successfully etc. This means there is a problem with the way asn1crypto parses this CMS. This seems like a bug with the package.

Is there another way this content should be extracted using asn1crypto? Is there a fix for this problem? Please assist.

Some additional info is that the ContentType of the EncryptedContentInfo is simply data and the error persists in asn1crypto Version 1.5.1 as well as older versions, such as 1.2.1.

MatthiasValvekens commented 1 year ago

Judging from the file extension and the error message, I guess that your payload uses the constructed (i.e. segmented) representation to encode the octet string with the encrypted content. This is legal in BER, but not in DER, and IIRC asn1crypto doesn't support constructed strings at all (can't check now, though).

They're very rare in the wild due to them being disallowed in DER, which is by far the most common ASN.1 encoding flavour.

It's hard to say for sure without having the actual payload in front of me, but I guess this is it. FWIW, I've successfully used asn1crypto with encrypted CMS messages in the past (all DER, though).

natzlob commented 1 year ago

Thanks for the response. I have also used asn1crypto successfully for encrypted CMS messages in the past. Here is the actual payload

b'0\x82\x03\xf6\x06\t*\x86H\x86\xf7\r\x01\x07\x010\x11\x06\x05+\x0e\x03\x02\x07\x04\x08\x01\xd2}\xecl3\x98\x0b\xa0\x82\x03\xd4\x04\x82\x03\xd0\xed\xc8\x0cO\x89n!\x880\xad\xb3R\x0c\x16\x92\xc2\xca\xc4\x96\xc5u\x1d\xa0X\xd2\x13H\x9aM#\x9a\xd8\x1e\x88\xc9\x95-\xf8`\xf5\xa6\x1bP\xf9\x91\xb3\xe3\xd8g\xaa*P\x1e\x0cE{%\x11.\xb0\x19;\xea\xa7\x06\xae\xb9\xf2W\x7fx\x88FB>\xfa\x81\x80/$AGjM\x82\xe5\x0cI\xcc\x16c\x14}3*D87\xb9\xf5a\x04\x1c\xd6\xa6qDp\xe1\x1a\xe9\xb4R\xe9\xc5\xd7p\n\xdc7\x05\xbe\xcf\x88`\xdd\x92\xf7\xb1\x8aC\xd8\xab/~\xe6F\x02nTu\x0b\xf4\xfa\x13K\xa4\x10\xc5\x8e&\xe9H\xaf\xe2`\xf2\xe4zx|\x9a\xf3\xc5\x92C~\x90\xd7\x10\xc5\x91\x83Je2s\xea?\x83xC\x9a\xecB\xdb\xc4\xc2\xf0\x1aG\x05\n\x10\x949D\xfdLe\xbc`\x19\x81a\xd9v,T\xb4\xf9u\xd9\x8b Bh.\xed\x15\x7f\xdd\xec\x05\x95F\x81\xc5\xe9_\x91\xc1\x1c\x13\xff\x16+\xc6\xe7\x08oJ\x80?\xf48\x8b\x16\x07\x12$\x19\xd7`\n;\x07F\xb5E{\x19\x9dk\'\x89T;kr<\x13\xf1\x02&\x18LId\xf6\x0e\x0eEG\xcdT"K\xbbQ\xa6\x9f\xd6\xc8\x83\xe4\xd1\xbaD$\xe2\xb1\xdc\xae\xb6\x14\xbf\xa1\xd3\xe6\xc9\xd1\x15yY\x1a\xccc\xab_?c\x11\xf8\xca\xb4\x81o\x91\x1c\xa5I\xbeq\xacvI\xb3;\x03\xe0i\xff\xf6\x0f\x99\r\x16N\x0f\x1d\x11\x91\x8a\x0b\xfb\x83\xea)y\xf1A1\x19\xa0-s\x07\t\xa3\x0c\x18!\x8e\x04m(,;b\x8bS\xa7\xbd\xfbp\xeb\xc6m0\x02\xa2/\xcc&D\xcf\xfd#\xf0\x1e=\x04\xa5=\xe9P&\x95l\xdfl\xb6-=y9\x1bH\xfc\xbd\xd1p\x0f\xd3U\xe0C\xf7\xbd\xc8\xf8o\x87\xe5zM\xa6\x1a\x9c\x80\xd9\xd2\x11\xfb\x92\xb3\xd1\t\x014\xa9[D\x86\xea/\x13\xfe>1$\xe9\xd7T\x80B\x1d+\xb6[\xd6\xb1\xcb]\xd9<X\xc8\xe9\xb0\x84\x96\x87\xa0\x9a%\xd5\xaa\x05\xf8X\xbe\x04\x1d\x81\xbc$\xb3_\xc6\xa2\xe6\x11\x918\x88?M\xd7\xa6\x1b}\xd7J\x15\xf8`ks\x08&\xb6Q\xc3\x9a{\xb8o\xe1\x9f\\\x17\xdd\x17\x0e|<\x05\x89\x07\xd3\xb9mK sb\xb4$LjuQ\xe2\xdeZ#v\xfd~y^\xc4\x12`\xae\xa9\xed\xf3\xc9\xbaE\xdbM\xe0\xef\xd6\xc6\x18\x8b\xf3@\xbdb\x9e\xf1gne\xb8\x8b\x90/\xe8\x80\x07\x1d\xfe\x1d\xd8\xae]\x8b\xfb\x12\xb3\x13\xf8*bD\x87\x14\xe5\x0e^\xd2Wq_E\xb8qQ\x8c\xb7m\x85\x81c\r\x89r\xd6\x10\x91\x99\x91\xd8\x0bY\xd6$\xa2\x18\x0c\xa9]\xa8|\x18Cs0*\x9d_\xb3)\xbe\xc9\xa8\x00$\xa0\xda\x0e\x1d\x1f_\x8b\xb6\x1f@X)\x91"8\x89IK\xa5\xbc\xae\xbd;\x86\xf3&\x95It\xb7\xf0\x974)\xa3 \xe7\x1f\xf0\x0b9\xf2\r1u\x07\x92\x80\xe4\xda^\xaf\xc7\xc3\x910\xa17\xda\xe2\xa4\xf4\xd1\x12\xb0ym\x04\x04.u\xe9\xc9\x98\xbeW4\xa2\x9f\xff;\x9b\x82p\xaf\x8f\xaa\nDNL/C\x162q*p\xfd\xe2\xa1\xf8\xed\xd4\x81#\xf8Q\t\x8f*\x1d\xfb\xcd6x2\xb1%\x8f\x0b!\xbb{\x88_\xedO<\x94-5D\xd6\xc9\xd4B\xa4)\xdep\x8c\x01\xe5\xa1n\x97\\\x16\xc4\x1a\x11Q\x8c\x83\xaf\x911\x13X\xd4\x93\xef\x01\xb4\xef\x85N%\xaa\xa7\x8d\xa6!\\\xb2\xbbY\x80\xd8\xe2*i6\xeb\x89\x86\x84v\x85~\xdej\xba,x_\x13\xd7\xe7\xc4\xb1\xc5P\x0e\x9b\xf3\x92\x89\x84\xdbx\xbf\xe6\x05\x1cl\xcc\xec\x19H\xea\x11\xd8D\x08\xac>\x97\xd0\xebI\xeb\x9d\x1a\xfb\x1b\xfa^\x1f\xcc\t*T\xed\xbd\x91\xabxV\xec\xaf\xf2\x91\x0es\xc9\xeaw\xb2\x1f\xf9\xe1\x0b\xc2\x911\xc0\x7f\x9f\xc10\x03\xf7c\x1a\x9b6\x82\xef\xc5\xea\xd2[S\xb0d1\xec)\xf0U\xf8\x08\x92\t8\xdf\xcf9\xb6>\xdb\xca\xd6\x0b\r\xfc\xb4=j'

If this is constructed and not supported by asn1crypto, do you have any suggested alternatives for me?

MatthiasValvekens commented 1 year ago

Ah, it's actually different: the CMS spec mandates implicit tagging for the encryptedContent field; your payload has explicit tagging there.

The reason why this shows up as an encoding method error is because explicit values are always constructed, whereas a "naked" octet string would be primitive.

So the data is invalid, but you can work around it by copy-pasting asn1crypto's EncryptedContentInfo class and replacing the implicit tag with explicit... That won't work on valid data, though... (:

natzlob commented 1 year ago

Thanks. Is there a way to define the class to ignore the implicit/explicit tag altogether and make it compatible with data either correctly or incorrectly tagged?

grk-it commented 1 year ago

@natzlob there's a PR now that takes care of this issue (assuming that payload came from the golang scep client): https://github.com/smallstep/pkcs7/pull/9

jinhua115 commented 1 year ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。