-
Notifications
You must be signed in to change notification settings - Fork 7.9k
This PR adds support for CMS. #5251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I am thinking of adding some additional capability to express DER/PEM/CMS output in openssl_cms_sign. This provides a bit more flexibility beyond email of the CMS routines. |
Please note a additional commits that provide for use and testing of different encodings. |
Just had a quick look and essentially it is pkcs7 moved to CMS which I think is probably a good way how to get it finally in. It might be worth to merge some common parts together. It would be also good to have a way to get I need to do a bit more thorough review but could you please clean it up a little bit. Mainly those parts:
|
@bukka Thank you very much for your review. I'll take a look at code reuse. I think there should be a bit, but some logic has changed. For instance CMS_ContentInfo really is an opaque struct. If you like, what I can do is expose the various cms_get0 functions that have same semantic value as poking around the PKCS7 struct. Wilco on the rest. |
Hi, I've looked at factoring out code to create static functions. At the end of the day, it's not worth it for several reasons:
In the last commit I did my best to bring the coding style in line with what you would expect. I welcome further edits on top if you spot any issues. |
@bukka any chance to move this one along? |
Added some comments but looks mostly good. |
Not yet safe to merge. Look for another commit shortly. |
@bukka Please have one more look. Thanks! |
But it does not fail, does it? |
It does on Appveyor for some reason - sometimes. Serious head scratching going on here. |
@cmb69 ok, I see. I hadn't realized that an XFAIL would warn on a pass. Suggestions? |
Well, is it possible that the issue is due to text mode translation (LF <-> CRLF)? |
I don't think so. When it blows up, what I am seeing is garbage out of CMS_encrypt: an invalid der file is being created, and no error is produced. |
Also- I think I did try setting CMS_BINARY and the same issue occurred. Again, it only seems to happen periodically with Appveyor. |
Is it really CMS_encrypt producing garbage, or is there a chance that another test run in parallel interferes (maybe due to an issue with tmpname on Windows, or whatever)? Anyhow, I would suggest to dynamically mark the test as "xfail" on Windows (you can just replace the "skip" argument of the print statement with "xfail"; ideally add some reason for why it is marked as xfail), so that it is run (and as such produces a diff), and also because the test ought to pass on Windows. The warning, in case the test succeedes, isn't a real issue. |
Hmm that's strange. Might be worth to add some debugging output (e.g. openssl errors) or maybe hack it a bit so more info is visible in AppVeyor. If skip or xfail is added, it should be clear what the reason is for that so we are sure that it's not a real issue. |
ok, i'm going to trim down the test to make sure there's no extraneous gunk |
Just to follow up, the test is currently passing, so it is possible there was something going on with tempnam() on Windows. I propose to just do a bunch of git push -fs during the week to see if the problem recurs. |
FYI I pounded the CI servers all day today and didn't run into any CMS-related failures. |
Fine, thanks for checking the AppVeyor issue! I'm not sure what to do with the RFC. I don't think this PR needs an RFC. |
@cmb69 I am happy to retire the RFC of course if the maintainers would just like to merge. I would like to retain it in the archives, because it will help with documentation. |
Yes, the RFC is definitely very useful for the documentation, and UPGRADING could just get a link to the RFC instead of lengthy explanation. |
*/ | ||
function openssl_cms_decrypt(string $infilename, string $outfilename, $recipcert, $recipkey, int $encoding = OPENSSL_ENCODING_SMIME): bool {} | ||
|
||
function openssl_cms_read(string $infilename, &$certs): bool {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any better type possible for $certs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For references, the type is only checked on input, but this is an out parameter. So no, no better type possible for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That and this is directly analogous to the pkcs7 call.
is an update to PKCS7. The functions are analogous BUT NOT IDENTICAL to openssl_pkcs7*. In particular, support for different encodings (PEM, DER, SMIME) is now available.
@bukka good to go? |
Thank you all! |
I've applied a small memory leak fix in 57e17e5. |
> - Added openssl_cms_encrypt() encrypts the message in the file with the > certificates and outputs the result to the supplied file. > - Added openssl_cms_decrypt() that decrypts the S/MIME message in the file > and outputs the results to the supplied file. > - Added openssl_cms_read() that exports the CMS file to an array of PEM > certificates. > - Added openssl_cms_sign() that signs the MIME message in the file with > a cert and key and output the result to the supplied file. > - Added openssl_cms_verify() that verifies that the data block is intact, > the signer is who they say they are, and returns the certs of the signers. Refs: * https://wiki.php.net/rfc/add-cms-support * https://github.com/php/php-src/blob/c0172aa2bdb9ea223c8491bdb300995b93a857a0/UPGRADING#L727-L736 * php/php-src#5251 * php/php-src@8583b8a Includes unit tests.
> Added Cryptographic Message Syntax (CMS) (RFC 5652) support composed of > functions for encryption, decryption, signing, verifying and reading. The > API is similar to the API for PKCS #7 functions with an addition of new > encoding constants: OPENSSL_ENCODING_DER, OPENSSL_ENCODING_SMIME and > OPENSSL_ENCODING_PEM. And from the RFC: > 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 Refs: * https://wiki.php.net/rfc/add-cms-support * https://github.com/php/php-src/blob/c0172aa2bdb9ea223c8491bdb300995b93a857a0/UPGRADING#L603-L608 * php/php-src#5251 * php/php-src@8583b8a Includes unit test.
For both openssl_pkcs7_decrypt and openssl_cms_decrypt, what is the reason for It doesn't look like there's test coverage for such usage. |
Hi @nikic I think the magic is in php_openssl_pkey_from_zval() which does indeed try to go hunting for a private key in a cert. I haven't chased this down for the cms routine, but a test case would not be out of order. |
Hi everyone,
This is my first PR for this project. It contains support for CMS, which is RFC 5652. The code borrows heavily from earlier work, because mostly speaking CMS is an incremental upgrade of PKCS#7. The notable changes are these:
CMS is not present in all versions of OpenSSL. Notably Apple is doing something funky these days with LibreSSL. No idea how they are compiling PHP, but if a dependency is required, it is not yet in this PR.