# ContentInfo
`ContentInfo` is the outer CMS envelope — every CMS structure is wrapped in a `ContentInfo`
SEQUENCE. It is the standard entry point for parsing any CMS payload.
## Class
```python
class ContentInfo:
@staticmethod
def from_der(data: bytes) -> ContentInfo: ...
# Parse a DER- or BER-encoded ContentInfo SEQUENCE.
def to_der(self) -> bytes: ...
content_type_oid: ObjectIdentifier
# e.g. ID_SIGNED_DATA, ID_ENVELOPED_DATA, ID_ENCRYPTED_DATA, …
content: bytes
# Raw bytes of the content field (including the [0] EXPLICIT tag for most types).
```
## Usage
```python
from synta.cms import ContentInfo, ID_SIGNED_DATA, ID_ENVELOPED_DATA, ID_ENCRYPTED_DATA
data = open("message.p7m", "rb").read()
ci = ContentInfo.from_der(data)
print(ci.content_type_oid) # e.g. ObjectIdentifier("1.2.840.113549.1.7.2")
if ci.content_type_oid == ID_SIGNED_DATA:
# ci.content includes the [0] EXPLICIT wrapper; strip it to get the inner SEQUENCE.
import synta
from synta.cms import SignedData
dec = synta.Decoder(ci.content, synta.Encoding.BER)
inner = dec.decode_explicit_tag(0)
sd = SignedData.from_der(inner.remaining_bytes())
print(f"Signers: {len(sd.signer_infos)}")
elif ci.content_type_oid == ID_ENVELOPED_DATA:
import synta
from synta.cms import EnvelopedData
dec = synta.Decoder(ci.content, synta.Encoding.BER)
inner = dec.decode_explicit_tag(0)
ed = EnvelopedData.from_der(inner.remaining_bytes())
# decrypt with ed.decrypt(private_key)
elif ci.content_type_oid == ID_ENCRYPTED_DATA:
import synta
from synta.cms import EncryptedData
dec = synta.Decoder(ci.content, synta.Encoding.BER)
inner = dec.decode_explicit_tag(0)
enc = EncryptedData.from_der(inner.remaining_bytes())
# decrypt with enc.decrypt(key)
```
See also the [CMS Overview](overview.md) for a summary of all content types.