====== 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.