rfc:add-cms-support

PHP 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 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

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

rfc/add-cms-support.txt · Last modified: 2020/05/13 19:45 by elear