DRAFT v0.6 24-11-2017, martin.paljak@eesti.ee
CDOC is a file format for storing encrypted data together with data for/about intended recipients.
The main goals of CDOC v2.0 format over CDOC v1.0 (and CDOC v1.1) are resource-effectiveness when processing containers (less XML parsing), compatibility with ASiC containers (based on OpenDocument v1.2 ZIP packages) and general alignment with newer and future standards and specifications.
It defines and clarifies the subset of relevant standards and provides guidelines and requirements for compliant implementations.
- [ODF] OpenDocument v1.2 part 3: packages
- [ASIC1] ETSI EN 319 162-1 V1.1.1 (ASiC baseline containers)
- [ASIC2] ETSI EN 319 162-2 V1.1.1 (Additional ASiC containers)
- [XML-ENC] XML Encryption Syntax and Processing
- [XML-ENC1] XML Encryption Syntax and Processing Version 1.1
- [DSIG] XML Signature Syntax and Processing (Second Edition)
CDOC v2.0 files are essentially OpenDocument v1.2 containers, conforming to OpenDocument Extended Package ([ODF] 2.2.2). The mime type is application/x-cdoc+zip
and recommended extension .cdoc
.
Information about transport keys, recipients etc is stored in META-INF/recipients.xml
which conforms to XML-ENC1 standard and schema.
This arrangement is comparable to ASiC-S ODF containers.
Bold is noteworthy, italic is minor/obvious.
- Usage of ODF ZIP container instead of XML as the overall envelope
- Encapsulation of multiple files is resource-efficient ZIP instead of XML+Base64
- XML actually validates against XML-ENC schema
- Introduction of AES-256 GCM as the default data encipherement algorithm instead of AES-128 CBC
- Addition of ECC support for recipient key info in addition to RSA, as described in XML-ENC1 5.6.4
Overall ZIP container of example.cdoc
:
example.cdoc
|-- mimetype
|-- META-INF
| |-- manifest.xml
| `-- recipients.xml
`-- payload.zip
Where:
mimetype
containsapplication/x-cdoc+zip
manifest.xml
contains
<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
manifest:version="1.2">
<manifest:file-entry manifest:full-path="/"
manifest:media-type="application/x-cdoc+zip"/>
<manifest:file-entry manifest:full-path="payload.zip"
manifest:media-type="application/zip"
manifest:size="..."/>
</manifest:manifest>
recipients.xml
looks like
<?xml version="1.0" encoding="UTF-8"?>
<xenc:EncryptedData xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:dsig11="http://www.w3.org/2009/xmldsig11#"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
xmlns:xenc11="http://www.w3.org/2009/xmlenc11#">
<xenc:EncryptionMethod Algorithm="..."/>
<ds:KeyInfo>...</ds:KeyInfo>
...
<xenc:CipherData>...</xenc:CipherData>
</xenc:EncryptedData>
- The mime type of CDOC v2.0 is
application/x-cdoc+zip
- The file extension SHOULD be
.cdoc
- The mime type SHOULD be present in Zip comment (ASiC 6.2.1 clause 3)
- The
mimetype
file MUST be present, together with themedia-type
manifest element for the package (See OpenDocument: 3.3 MIME Media Type) - The format MAY be used with ZIP64 extension.
- Storage of encrypted file MUST follow the rules laid down in OpenDocument section 3.4.1, regarding actual (decrypted) payload size in manifest. Usage of STORED method is NOT required.
- The container MAY include other files in addition to
META-INF/recipients.xml
andpayload.zip
- Plaintext files MUST be encapsulated in a ZIP container before encryption, which implementations SHOULD display inline after decryption (ASiC baseline B.1.3)
- The name of the encapsulated payload ZIP file SHOULD be
payload.zip
. The actual payload file within the ZIP container MUST be indicated in the URI attribute ofEncryptedData/xenc:CipherData/xenc:CipherReference
element. - The payload file MUST reside in the container root folder.
- The payload of the package MUST NOT contain subfolders. All encrypted files MUST reside in the root folder.
- The ZIP compression method of the files in the payload ZIP MUST be DEFLATE.
META-INF/recipients.xml
MUST validate against [XML-ENC1] schema
- Implementations MUST follow the Robustness principle
- Implementations SHOULD allow to decrypt containers which lack proper MIME information, based only on the presence of
META-INF/recipients.xml
- Implementations SHOULD allow to decrypt containers which lack proper MIME information, based only on the presence of
- Implementations SHOULD support ZIP64 for files larger than 4GB
- Lack of support for ZIP64 MUST be documented in accompanying documentation
- Binary formatting of encrypted payload (IV, padding, authentication tag) MUST conform to [XML-ENC1] 5.2: Block Encryption Algorithms.
- Implementations MUST support AES-256 GCM transport key encryption with RSA PKCS#1 v1.5 and ECDH-ES with AES KeyWrap (usage with ID-card). Implementations MAY support additional schemes (like out-of-band transport keys or other transport ciphes).
The use with Estonian ID-card defaults to:
- RSA 2048 PKCS#1 v1.5 for transport key encryption
- AES-GCM 256 for payload encryption
META-INF/recipients.xml
snippet:
<EncryptedData>
<EncryptionMethod Algorithm='http://www.w3.org/2009/xmlenc11#aes256-gcm'/>
<KeyInfo>
<EncryptedKey>
<EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-1_5'/>
...
</EncryptedKey>
</KeyInfo>
...
</EncryptedData>
- P-384 (secp384r1) ECDH-ES with Concat KDF and AES KeyWrap for transport key encryption
- AES-GCM 256 for payload encryption
META-INF/recipients.xml
snippet:
<EncryptedData>
<EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
<KeyInfo>
<EncryptedKey Recipient="...">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#kw-aes256"/>
<KeyInfo>
<AgreementMethod Algorithm="http://www.w3.org/2009/xmlenc11#ECDH-ES">
<KeyDerivationMethod Algorithm="http://www.w3.org/2009/xmlenc11#ConcatKDF">
<ConcatKDFParams AlgorithmID="..." PartyUInfo="..." PartyVInfo="...">
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha384"/>
</ConcatKDFParams>
</KeyDerivationMethod>
<OriginatorKeyInfo>
<KeyValue>
<ECKeyValue>
<NamedCurve URI="urn:oid:1.3.132.0.34"/>
<PublicKey>...</PublicKey>
</ECKeyValue>
</KeyValue>
</OriginatorKeyInfo>
<RecipientKeyInfo>
<X509Data>
<X509Certificate>...</ds:X509Certificate>
</X509Data>
</RecipientKeyInfo>
</AgreementMethod>
</KeyInfo>
<CipherData>
<CipherValue>...</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
...
</EncryptedData>
READMe.txt
is encrypted with AES-GCM 256 and the key itself is supposedly known to the receiver via out of band means
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#' MimeType="text/plain" />
<EncryptionMethod Algorithm='http://www.w3.org/2009/xmlenc11#aes256-gcm'/>
<ds:KeyInfo xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>
<ds:KeyName>The pre-shared key</ds:KeyName>
</ds:KeyInfo>
<CipherData><CipherReference URI="README.txt"/></CipherData>
</EncryptedData>
The file Important.bdoc
is encrypted with AES-256 in GCM mode. The transport key is encrypted with RSA PKCS#1 and the resulting cryptogram is included.
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#' MimeType="application/vnd.etsi.asic-e+zip"/>
<EncryptionMethod Algorithm='http://www.w3.org/2009/xmlenc11#aes256-gcm'/>
<ds:KeyInfo xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>
<EncryptedKey Recipient="PALJAK,MARTIN,38207162722,DIGI-ID">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIE6...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<CipherData>
<CipherValue>h3SJo...</CipherValue>
</CipherData>
</EncryptedKey>
</ds:KeyInfo>
<CipherData><CipherReference URI="Important.bdoc"/></CipherData>
</EncryptedData>
- v2.0 has the bytes
PK
as the first two bytes of the file - v1.1 can be differentiated from v1.1 by the data encryption algorihtm in
/xenc:EncryptedData/xenc:EncryptionMethod/@Algorithm
:- v1.0 -
http://www.w3.org/2001/04/xmlenc#aes128-cbc
- v1.1 -
http://www.w3.org/2009/xmlenc11#aes256-gcm
- v1.0 -
- v1.0 and v1.1 has the XML header
<?
or relevant BOM in the first bytes of the file
The original goal was to accommodate signed (XAdES) and encrypted payloads inside a single ASiC container (.bdoc). This already sets the scene for capabilities of potential implementors: ZIP processing (for container) and XML processing (for signatures.xml as well as manifest.xml) is readily available in all modern development platforms.
Both ZIP and ODF have encryption capabilities, but mostly bound to a fixed password-based key derivation scheme and implementation-specific if not proprietary encryption options. Re-implementation of such formats would give no flexibility and no real cross-usage benefits.
For actual binary storage of encrypted data inside the ZIP container, formats such as CMS aka S/MIME (RFC 5652) or OpenPGP (RFC 4880) could be used, but would offer little benefit in the container context (and thus no real benefit in cross-usage).
XML - while somewhat morally outdated - is by definition extensible and thus allows to build upon the base specification without heavily changing the implementations.