====== PHP RFC: Add CMS Support ======
* Version: 0.9
* Date: 2020-05-13
* Author: Eliot Lear, lear@lear.ch
* Status: Implemented (PHP 8.0)
* First Published at: http://wiki.php.net/rfc/add-cms-support
===== Introduction =====
PHP has for some time incorporated support for PKCS#7 sign, verify, encrypt, decrypt, and read operations.
Cryptographic Message Syntax (CMS) is a newer version of PKCS#7. Having been around some time, CMS is used in both
email messaging as well as signature verification operations relating to IoT devices.
===== Proposal =====
It is proposed that analogous functions be created for CMS. These would be as follows:
^ PKCS#7 function ^ new CMS function ^
|openssl_pkcs7_encrypt() | openssl_cms_encrypt()|
|openssl_pkcs7_decrypt() | openssl_cms_decrypt()|
|openssl_pkcs7_sign() | openssl_cms_sign()|
|openssl_pkcs7_verify () | openssl_cms_verify()|
|openssl_pkcs7_read () | openssl_cms_read()|
As currently stands, the CMS sign and verify functions now can take as an argument the encoding method (DER/CMS/PEM).
=== Calling Interface ===
function openssl_cms_sign(string $infile, string $outfile, $signcert, $signkey, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, ?string $extracertsfilename = null): bool {}
This function signs a file with an X.509 certificate and key.
Arguments:
* $infile - the name of the file to be signed
* $outfile - the name of the file to deposit the results
* $signcert - the name of the file containing the signing certificate
* $signkey - the name of file containing the key associated with $signcert
* $headers - an array of headers to be included in S/MIME output
* $flags - flags to be passed to cms_sign()
* $encoding - the encoding of the output file
* $extracertsfilename - intermediate certificates to be included in the signature
function openssl_cms_verify(string $filename, int $flags = 0, string $signerscerts = UNKNOWN, array $cainfo = UNKNOWN, string $extracerts = UNKNOWN, string $content = UNKNOWN, string $pk7 = UNKNOWN, string $sigfile = UNKNOWN, $encoding = OPENSSL_ENCODING_SMIME ): bool {}
This function verifies a CMS signature, either attached or detached, with the specified encoding.
Arguments:
* $filename - the input file
* $flags - flags that would be passed to cms_verify
* $signercerts - a file that the signer certificate and optionally intermediate certificates
* $cainfo - an array containing self-signed certificate authority certificates
* $extracerts - a file containing additional intermediarte certificates
* $content - a file pointing to the content when signatures are detached
* $pk7 - a file to save the signature to
* $encoding - one of three supported encodings (PEM/DER/SMIME).
Returns TRUE on success and FALSE on failure.
function openssl_cms_encrypt(string $infile, string $outfile, $recipcerts, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher = OPENSSL_CIPHER_RC2_40): bool {}
This function encrypts content to one or more recipients, based on the certificates that are passed to it.
Arguments:
* $infile - the file to be encrypted
* $outfile - the output file
* $recipcerts - recipients to encrypt to
* $headers - headers to include when S/MIME is usd
* $flags - Flags to be passed to CMS_sign
* $encoding - an encoding to output
* $cipher - a cypher to use
Return values: TRUE on success or FALSE on failure.
function openssl_cms_decrypt(string $infilename, string $outfilename, $recipcert, $recipkey = UNKNOWN, int $encoding = OPENSSL_ENCODING_SMIME): bool {}
Decrypts a CMS message.
Arguments:
* $infilename - the name of a file containing encrypted content
* $outfilename - the name of the file to deposit the decrypted content
* $recipcert - the name of the file containing a certificate of the recipient
* $recipkey - the name of the file containing a PKCS#8 key
* $encoding - the encoding of the input file.
Returns TRUE on success and FALSE on failure.
function openssl_cms_read(string $infilename, &$certs): bool {}
Performs the exact analog to openssl_pkcs7_read().
This is **nearly** identical to the PKCS#7 calling interface, the only exception being $encoding.
===== Backward Incompatible Changes =====
None.
===== Proposed PHP Version(s) =====
PHP 8.0
===== RFC Impact =====
==== To SAPIs ====
The only change is an additional API. No modifications to existing APIs.
==== To Existing Extensions ====
New functions are added to ext/openssl. No existing functions are changed.
==== To Opcache ====
No known impact.
==== New Constants ====
Several new constants are defined to indicate encoding, as follows:
OPENSSL_ENCODING_CMS /* encoding is a CMS-encoded message */
OPENSSL_ENCODING_DER /* encoding is DER (Distinguished Encoding Rules) */
OPENSSL_ENCODING_PEM /* encoding is PEM (Privacy-Enhanced Mail) */
The following analogs to PKCS#7 are also added:
OPENSSL_CMS_DETACHED
OPENSSL_CMS_TEXT
OPENSSL_CMS_NOINTERN
OPENSSL_CMS_NOVERIFY
OPENSSL_CMS_NOCERTS
OPENSSL_CMS_NOATTR
OPENSSL_CMS_BINARY
OPENSSL_CMS_NOSIGS
==== php.ini Defaults ====
No change.
===== Open Issues =====
No known issues.
===== Unaffected PHP Functionality =====
As these are new functions, no side effects to other functions should be expected.
===== Future Scope =====
Currently, as with the PKCS#7 calls, these calls take files as arguments. Future work should
focus on in-memory signing/encrypting/verifying/decrypting operations.
===== Proposed Voting Choices =====
Include these so readers know where you are heading and can discuss the proposed voting options.
===== Patches and Tests =====
This capability is available for inspection as [[https://github.com/php/php-src/pull/5251|PR #5251]].
Tests are available in that PR. This PR is subject to change of course, based on community feedback.
===== Proposed Voting Choices =====
Yes/No.
===== Implementation =====
After the project is implemented, this section should contain
- the version(s) it was merged into
- a link to the git commit(s)
- a link to the PHP manual entry for the feature
- a link to the language specification section (if any)
===== References =====
- [[https://www.rfc-editor.org/rfc/rfc5652.html|RFC 5652]]
- [[https://www.rfc-editor.org/rfc/rfc8520.html|RFC 8520]]
- [[https://github.com/php/php-src/pull/5251|Git Pull Request 5251]]
===== Rejected Features =====
Keep this updated with features that were discussed on the mail lists.