1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Add support for Cryptographic Message Syntax (CMS)

It add CMS (RFC 5652) support, which 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.
This commit is contained in:
Eliot Lear
2020-03-09 16:01:20 +01:00
committed by Jakub Zelenka
parent 7439941d55
commit 8583b8a9bf
20 changed files with 1746 additions and 6 deletions

View File

@@ -1,2 +1,2 @@
OpenSSL
Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar
Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar, Eliot Lear

View File

@@ -16,6 +16,7 @@
| Pierre-Alain Joye <pierre@php.net> |
| Marc Delling <delling@silpion.de> (PKCS12 functions) |
| Jakub Zelenka <bukka@php.net> |
| Eliot Lear <lear@ofcourseimright.com> |
+----------------------------------------------------------------------+
*/
@@ -53,6 +54,7 @@
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/pkcs12.h>
#include <openssl/cms.h>
/* Common */
#include <time.h>
@@ -115,6 +117,16 @@ enum php_openssl_cipher_type {
PHP_OPENSSL_CIPHER_DEFAULT = PHP_OPENSSL_CIPHER_RC2_40
};
/* Add some encoding rules. This is normally handled through filters
* in the OpenSSL code, but we will do that part as if we were one
* of the OpenSSL binaries along the lines of -outform {DER|CMS|PEM}
*/
enum php_openssl_encoding {
ENCODING_DER,
ENCODING_SMIME,
ENCODING_PEM,
};
/* {{{ openssl_module_entry
*/
zend_module_entry openssl_module_entry = {
@@ -1075,6 +1087,15 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("PKCS7_BINARY", PKCS7_BINARY, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PKCS7_NOSIGS", PKCS7_NOSIGS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_DETACHED", CMS_DETACHED, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_TEXT", CMS_TEXT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOINTERN", CMS_NOINTERN, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOVERIFY", CMS_NOVERIFY, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOCERTS", CMS_NOCERTS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOATTR", CMS_NOATTR, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_BINARY", CMS_BINARY, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOSIGS", CMS_NOSIGS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PADDING", RSA_PKCS1_PADDING, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_SSLV23_PADDING", RSA_SSLV23_PADDING, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_CS|CONST_PERSISTENT);
@@ -1118,6 +1139,11 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);
#endif
/* Register encodings */
REGISTER_LONG_CONSTANT("OPENSSL_ENCODING_DER",ENCODING_DER,CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_ENCODING_SMIME",ENCODING_SMIME,CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_ENCODING_PEM",ENCODING_PEM,CONST_CS|CONST_PERSISTENT);
/* Determine default SSL configuration file */
config_filename = getenv("OPENSSL_CONF");
if (config_filename == NULL) {
@@ -4777,22 +4803,17 @@ PHP_FUNCTION(openssl_pkcs7_verify)
php_openssl_store_errors();
goto clean_exit;
}
if (datafilename) {
if (php_openssl_open_base_dir_chk(datafilename)) {
goto clean_exit;
}
dataout = BIO_new_file(datafilename, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY));
if (dataout == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (p7bfilename) {
if (php_openssl_open_base_dir_chk(p7bfilename)) {
goto clean_exit;
}
@@ -5309,6 +5330,748 @@ clean_exit:
/* }}} */
/* {{{ CMS S/MIME functions taken from PKCS#7 functions */
/* {{{ proto bool openssl_cms_verify(string filename, int flags [, string signerscerts [, array cainfo [, string extracerts [, string content [, string pk7]]]], string sigfile, int encoding])
Verifies that the data block is intact, the signer is who they say they are, and returns the CERTs of the signers */
PHP_FUNCTION(openssl_cms_verify)
{
X509_STORE * store = NULL;
zval * cainfo = NULL;
STACK_OF(X509) *signers= NULL;
STACK_OF(X509) *others = NULL;
CMS_ContentInfo * cms = NULL;
BIO * in = NULL, * datain = NULL, * dataout = NULL, * p7bout = NULL;
BIO *certout = NULL, *sigbio = NULL;
zend_long flags = 0;
char * filename;
size_t filename_len;
char * extracerts = NULL;
size_t extracerts_len = 0;
char * signersfilename = NULL;
size_t signersfilename_len = 0;
char * datafilename = NULL;
size_t datafilename_len = 0;
char * p7bfilename = NULL;
size_t p7bfilename_len = 0;
char * sigfile = NULL;
size_t sigfile_len = 0;
zend_long encoding = ENCODING_SMIME;
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|p!ap!p!p!p!l", &filename, &filename_len,
&flags, &signersfilename, &signersfilename_len, &cainfo,
&extracerts, &extracerts_len, &datafilename, &datafilename_len,
&p7bfilename, &p7bfilename_len,
&sigfile, &sigfile_len, &encoding) == FAILURE) {
RETURN_THROWS();
}
if (php_openssl_open_base_dir_chk(filename)) {
goto clean_exit;
}
in = BIO_new_file(filename, PHP_OPENSSL_BIO_MODE_R(flags));
if (in == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
if (sigfile && (flags & CMS_DETACHED)) {
sigbio = BIO_new_file(sigfile, PHP_OPENSSL_BIO_MODE_R(flags));
if (encoding == ENCODING_SMIME) {
php_error_docref(NULL, E_WARNING,
"Detached signatures not possible with S/MIME encoding");
goto clean_exit;
}
} else {
sigbio = in; /* non-detached signature */
}
switch (encoding) {
case ENCODING_PEM:
cms = PEM_read_bio_CMS(sigbio, NULL, 0, NULL);
datain = in;
break;
case ENCODING_DER:
cms = d2i_CMS_bio(sigbio, NULL);
datain = in;
break;
case ENCODING_SMIME:
cms = SMIME_read_CMS(sigbio, &datain);
break;
default:
php_error_docref(NULL, E_WARNING, "Unknown encoding");
goto clean_exit;
}
if (cms == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
if (encoding != ENCODING_SMIME && !(flags & CMS_DETACHED)) {
datain = NULL; /* when not detached, don't pass a real BIO */
}
if (extracerts) {
others = php_openssl_load_all_certs_from_file(extracerts);
if (others == NULL) {
goto clean_exit;
}
}
store = php_openssl_setup_verify(cainfo);
if (!store) {
goto clean_exit;
}
if (datafilename) {
if (php_openssl_open_base_dir_chk(datafilename)) {
goto clean_exit;
}
dataout = BIO_new_file(datafilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
if (dataout == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (p7bfilename) {
if (php_openssl_open_base_dir_chk(p7bfilename)) {
goto clean_exit;
}
p7bout = BIO_new_file(p7bfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
if (p7bout == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
}
#if DEBUG_SMIME
zend_printf("Calling CMS verify\n");
#endif
if (CMS_verify(cms, others, store, datain, dataout, (unsigned int)flags)) {
RETVAL_TRUE;
if (signersfilename) {
if (php_openssl_open_base_dir_chk(signersfilename)) {
goto clean_exit;
}
certout = BIO_new_file(signersfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
if (certout) {
int i;
signers = CMS_get0_signers(cms);
if (signers != NULL) {
for (i = 0; i < sk_X509_num(signers); i++) {
if (!PEM_write_bio_X509(certout, sk_X509_value(signers, i))) {
php_openssl_store_errors();
RETVAL_FALSE;
php_error_docref(NULL, E_WARNING, "Failed to write signer %d", i);
}
}
sk_X509_free(signers);
} else {
RETVAL_FALSE;
php_openssl_store_errors();
}
} else {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Signature OK, but cannot open %s for writing", signersfilename);
RETVAL_FALSE;
}
if (p7bout) {
PEM_write_bio_CMS(p7bout, cms);
}
}
} else {
php_openssl_store_errors();
RETVAL_FALSE;
}
clean_exit:
BIO_free(p7bout);
if (store) {
X509_STORE_free(store);
}
if (datain != in) {
BIO_free(datain);
}
if (sigbio != in) {
BIO_free(sigbio);
}
BIO_free(in);
BIO_free(dataout);
BIO_free(certout);
if (cms) {
CMS_ContentInfo_free(cms);
}
if (others) {
sk_X509_pop_free(others, X509_free);
}
}
/* }}} */
/* {{{ proto bool openssl_cms_encrypt(string infile, string outfile, mixed recipcerts, array headers [, int flags [,int encoding [, int cipher]]])
Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile */
PHP_FUNCTION(openssl_cms_encrypt)
{
zval * zrecipcerts, * zheaders = NULL;
STACK_OF(X509) * recipcerts = NULL;
BIO * infile = NULL, * outfile = NULL;
zend_long flags = 0;
zend_long encoding = ENCODING_SMIME;
CMS_ContentInfo * cms = NULL;
zval * zcertval;
X509 * cert;
const EVP_CIPHER *cipher = NULL;
zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
zend_string * strindex;
char * infilename = NULL;
size_t infilename_len;
char * outfilename = NULL;
size_t outfilename_len;
int need_final = 0;
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|lll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &encoding, &cipherid) == FAILURE) {
RETURN_THROWS();
}
if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
return;
}
infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags));
if (infile == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(flags));
if (outfile == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
recipcerts = sk_X509_new_null();
/* get certs */
if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) {
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zrecipcerts), zcertval) {
zend_resource *certresource;
cert = php_openssl_x509_from_zval(zcertval, 0, &certresource);
if (cert == NULL) {
goto clean_exit;
}
if (certresource != NULL) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
if (cert == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
}
sk_X509_push(recipcerts, cert);
} ZEND_HASH_FOREACH_END();
} else {
/* a single certificate */
zend_resource *certresource;
cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource);
if (cert == NULL) {
goto clean_exit;
}
if (certresource != NULL) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
if (cert == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
}
sk_X509_push(recipcerts, cert);
}
/* sanity check the cipher */
cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
if (cipher == NULL) {
/* shouldn't happen */
php_error_docref(NULL, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
cms = CMS_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, (unsigned int)flags);
if (cms == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
if (flags & CMS_PARTIAL && !(flags & CMS_STREAM)) {
need_final=1;
}
/* tack on extra headers */
if (zheaders && encoding == ENCODING_SMIME) {
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) {
zend_string *str = zval_try_get_string(zcertval);
if (UNEXPECTED(!str)) {
goto clean_exit;
}
if (strindex) {
BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
} else {
BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
}
zend_string_release(str);
} ZEND_HASH_FOREACH_END();
}
(void)BIO_reset(infile);
switch (encoding) {
case ENCODING_SMIME:
if (!SMIME_write_CMS(outfile, cms, infile, (int)flags)) {
php_openssl_store_errors();
goto clean_exit;
}
break;
case ENCODING_DER:
if (need_final) {
if (CMS_final(cms, infile, NULL, (unsigned int) flags) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (i2d_CMS_bio(outfile, cms) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
break;
case ENCODING_PEM:
if (need_final) {
if (CMS_final(cms, infile, NULL, (unsigned int) flags) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (flags & CMS_STREAM) {
if (PEM_write_bio_CMS_stream(outfile, cms, infile, flags) == 0) {
php_openssl_store_errors();
goto clean_exit;
}
} else {
if (PEM_write_bio_CMS(outfile, cms) == 0) {
php_openssl_store_errors();
goto clean_exit;
}
}
break;
default:
php_error_docref(NULL, E_WARNING, "Unknown OPENSSL encoding");
goto clean_exit;
}
RETVAL_TRUE;
clean_exit:
if (cms) {
CMS_ContentInfo_free(cms);
}
BIO_free(infile);
BIO_free(outfile);
if (recipcerts) {
sk_X509_pop_free(recipcerts, X509_free);
}
}
/* }}} */
/* {{{ proto bool openssl_cms_read(string P7B, array &certs)
Exports the CMS file to an array of PEM certificates */
PHP_FUNCTION(openssl_cms_read)
{
zval * zout = NULL, zcert;
char *p7b;
size_t p7b_len;
STACK_OF(X509) *certs = NULL;
STACK_OF(X509_CRL) *crls = NULL;
BIO * bio_in = NULL, * bio_out = NULL;
CMS_ContentInfo * cms = NULL;
int i;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &p7b, &p7b_len,
&zout) == FAILURE) {
RETURN_THROWS();
}
RETVAL_FALSE;
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(p7b_len, p7b);
bio_in = BIO_new(BIO_s_mem());
if (bio_in == NULL) {
goto clean_exit;
}
if (0 >= BIO_write(bio_in, p7b, (int)p7b_len)) {
php_openssl_store_errors();
goto clean_exit;
}
cms = PEM_read_bio_CMS(bio_in, NULL, NULL, NULL);
if (cms == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
switch (OBJ_obj2nid(CMS_get0_type(cms))) {
case NID_pkcs7_signed:
case NID_pkcs7_signedAndEnveloped:
certs = CMS_get1_certs(cms);
crls = CMS_get1_crls(cms);
break;
default:
break;
}
zout = zend_try_array_init(zout);
if (!zout) {
goto clean_exit;
}
if (certs != NULL) {
for (i = 0; i < sk_X509_num(certs); i++) {
X509* ca = sk_X509_value(certs, i);
bio_out = BIO_new(BIO_s_mem());
if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
add_index_zval(zout, i, &zcert);
BIO_free(bio_out);
}
}
}
if (crls != NULL) {
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
X509_CRL* crl = sk_X509_CRL_value(crls, i);
bio_out = BIO_new(BIO_s_mem());
if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
BUF_MEM *bio_buf;
BIO_get_mem_ptr(bio_out, &bio_buf);
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
add_index_zval(zout, i, &zcert);
BIO_free(bio_out);
}
}
}
RETVAL_TRUE;
clean_exit:
BIO_free(bio_in);
if (cms != NULL) {
CMS_ContentInfo_free(cms);
}
}
/* }}} */
/* {{{ proto bool openssl_cms_sign(string infile, string outfile, mixed signcert, mixed signkey, array headers [, int flags, int encoding [, string extracertsfilename]])
Signs the MIME message in the file named infile with signcert/signkey and output the result to file name outfile. headers lists plain text headers to exclude from the signed portion of the message, and should include to, from and subject as a minimum */
PHP_FUNCTION(openssl_cms_sign)
{
zval * zcert, * zprivkey, * zheaders;
zval * hval;
X509 * cert = NULL;
EVP_PKEY * privkey = NULL;
zend_long flags = 0;
zend_long encoding = ENCODING_SMIME;
CMS_ContentInfo * cms = NULL;
BIO * infile = NULL, * outfile = NULL;
STACK_OF(X509) *others = NULL;
zend_resource *certresource = NULL, *keyresource = NULL;
zend_string * strindex;
char * infilename;
size_t infilename_len;
char * outfilename;
size_t outfilename_len;
char * extracertsfilename = NULL;
size_t extracertsfilename_len;
int need_final = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppzza!|llp!",
&infilename, &infilename_len, &outfilename, &outfilename_len,
&zcert, &zprivkey, &zheaders, &flags, &encoding, &extracertsfilename,
&extracertsfilename_len) == FAILURE) {
RETURN_THROWS();
}
RETVAL_FALSE;
if (extracertsfilename) {
others = php_openssl_load_all_certs_from_file(extracertsfilename);
if (others == NULL) {
goto clean_exit;
}
}
privkey = php_openssl_evp_from_zval(zprivkey, 0, "", 0, 0, &keyresource);
if (privkey == NULL) {
if (!EG(exception)) {
php_error_docref(NULL, E_WARNING, "Error getting private key");
}
goto clean_exit;
}
cert = php_openssl_x509_from_zval(zcert, 0, &certresource);
if (cert == NULL) {
php_error_docref(NULL, E_WARNING, "Error getting cert");
goto clean_exit;
}
if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
goto clean_exit;
}
if ((encoding & ENCODING_SMIME) && (flags & CMS_DETACHED)) {
php_error_docref(NULL,
E_WARNING, "Detached signatures not possible with S/MIME encoding");
goto clean_exit;
}
/* a CMS struct will not be complete if either CMS_PARTIAL or CMS_STREAM is set.
* However, CMS_PARTIAL requires a CMS_final call whereas CMS_STREAM requires
* a different write routine below. There may be a more efficient way to do this
* with function pointers, but the readability goes down.
* References: CMS_sign(3SSL), CMS_final(3SSL)
*/
if (flags & CMS_PARTIAL && !(flags & CMS_STREAM)) {
need_final=1;
}
infile = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(flags));
if (infile == NULL) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Error opening input file %s!", infilename);
goto clean_exit;
}
outfile = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
if (outfile == NULL) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Error opening output file %s!", outfilename);
goto clean_exit;
}
cms = CMS_sign(cert, privkey, others, infile, (unsigned int)flags);
if (cms == NULL) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Error creating CMS structure!");
goto clean_exit;
}
if (BIO_reset(infile) != 0) {
php_openssl_store_errors();
goto clean_exit;
}
/* tack on extra headers */
if (zheaders && encoding == ENCODING_SMIME) {
int ret;
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, hval) {
zend_string *str = zval_try_get_string(hval);
if (UNEXPECTED(!str)) {
goto clean_exit;
}
if (strindex) {
ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str));
} else {
ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str));
}
zend_string_release(str);
if (ret < 0) {
php_openssl_store_errors();
}
} ZEND_HASH_FOREACH_END();
}
/* writing the signed data depends on the encoding */
switch (encoding) {
case ENCODING_SMIME:
if (!SMIME_write_CMS(outfile, cms, infile, (int)flags)) {
php_openssl_store_errors();
goto clean_exit;
}
break;
case ENCODING_DER:
if (need_final) {
if (CMS_final(cms, infile, NULL, (unsigned int) flags) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (i2d_CMS_bio(outfile, cms) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
break;
case ENCODING_PEM:
if (need_final) {
if (CMS_final(cms, infile, NULL, (unsigned int) flags) != 1) {
php_openssl_store_errors();
goto clean_exit;
}
}
if (flags & CMS_STREAM) {
if (PEM_write_bio_CMS_stream(outfile, cms, infile, flags) == 0) {
php_openssl_store_errors();
goto clean_exit;
}
} else {
if (PEM_write_bio_CMS(outfile, cms) == 0) {
php_openssl_store_errors();
goto clean_exit;
}
}
break;
default:
php_error_docref(NULL, E_WARNING, "Unknown OPENSSL encoding");
goto clean_exit;
}
RETVAL_TRUE;
clean_exit:
if (cms) {
CMS_ContentInfo_free(cms);
}
BIO_free(infile);
BIO_free(outfile);
if (others) {
sk_X509_pop_free(others, X509_free);
}
EVP_PKEY_free(privkey);
if (cert && certresource == NULL) {
X509_free(cert);
}
}
/* }}} */
/* {{{ proto bool openssl_cms_decrypt(string infilename, string outfilename, mixed recipcert [, mixed recipkey [, int encoding])
Decrypts the S/MIME message in the file name infilename and output the results to the file name outfilename. recipcert is a CERT for one of the recipients. recipkey specifies the private key matching recipcert, if recipcert does not include the key */
PHP_FUNCTION(openssl_cms_decrypt)
{
zval * recipcert, * recipkey = NULL;
X509 * cert = NULL;
EVP_PKEY * key = NULL;
zend_resource *certresval, *keyresval;
zend_long encoding = ENCODING_SMIME;
BIO * in = NULL, * out = NULL, * datain = NULL;
CMS_ContentInfo * cms = NULL;
char * infilename;
size_t infilename_len;
char * outfilename;
size_t outfilename_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppz|zl", &infilename, &infilename_len,
&outfilename, &outfilename_len, &recipcert,
&recipkey, &encoding) == FAILURE) {
RETURN_THROWS();
}
RETVAL_FALSE;
cert = php_openssl_x509_from_zval(recipcert, 0, &certresval);
if (cert == NULL) {
php_error_docref(NULL, E_WARNING, "Unable to coerce parameter 3 to x509 cert");
goto clean_exit;
}
key = php_openssl_evp_from_zval(recipkey ? recipkey : recipcert, 0, "", 0, 0, &keyresval);
if (key == NULL) {
if (!EG(exception)) {
php_error_docref(NULL, E_WARNING, "Unable to get private key");
}
goto clean_exit;
}
if (php_openssl_open_base_dir_chk(infilename) || php_openssl_open_base_dir_chk(outfilename)) {
goto clean_exit;
}
in = BIO_new_file(infilename, PHP_OPENSSL_BIO_MODE_R(CMS_BINARY));
if (in == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
out = BIO_new_file(outfilename, PHP_OPENSSL_BIO_MODE_W(CMS_BINARY));
if (out == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
switch (encoding) {
case ENCODING_DER:
cms = d2i_CMS_bio(in, NULL);
break;
case ENCODING_PEM:
cms = PEM_read_bio_CMS(in, NULL, 0, NULL);
break;
case ENCODING_SMIME:
cms = SMIME_read_CMS(in, &datain);
break;
default:
php_error_docref(NULL, E_WARNING,
"Unknown OPENSSL encoding");
goto clean_exit;
}
if (cms == NULL) {
php_openssl_store_errors();
goto clean_exit;
}
if (CMS_decrypt(cms, key, cert, NULL, out, 0)) {
RETVAL_TRUE;
} else {
php_openssl_store_errors();
}
clean_exit:
if (cms) {
CMS_ContentInfo_free(cms);
}
BIO_free(datain);
BIO_free(in);
BIO_free(out);
if (cert && certresval == NULL) {
X509_free(cert);
}
if (key && keyresval == NULL) {
EVP_PKEY_free(key);
}
}
/* }}} */
/* }}} */
/* {{{ proto bool openssl_private_encrypt(string data, string &crypted, mixed key [, int padding])
Encrypts data with private key */
PHP_FUNCTION(openssl_private_encrypt)

View File

@@ -129,6 +129,26 @@ function openssl_pkcs7_decrypt(string $infilename, string $outfilename, $recipce
function openssl_pkcs7_read(string $infilename, &$certs): bool {}
function openssl_cms_verify(string $filename, int $flags = 0, ?string $signerscerts = null, ?array $cainfo = null, ?string $extracerts = null, ?string $content = null, ?string $pk7 = null, ?string $sigfile = null, $encoding = OPENSSL_ENCODING_SMIME): bool {}
/** @param resource|string|array $recipcerts */
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 {}
/**
* @param resource|string $signcert
* @param resource|string|array $signkey
*/
function openssl_cms_sign(string $infile, string $outfile, $signcert, $signkey, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, ?string $extracertsfilename = null): bool {}
/**
* @param resource|string $recipcert
* @param resource|string|array $recipkey
*/
function openssl_cms_decrypt(string $infilename, string $outfilename, $recipcert, $recipkey, int $encoding = OPENSSL_ENCODING_SMIME): bool {}
function openssl_cms_read(string $infilename, &$certs): bool {}
/** @param resource|string|array $key */
function openssl_private_encrypt(string $data, &$crypted, $key, int $padding = OPENSSL_PKCS1_PADDING): bool {}

View File

@@ -196,6 +196,49 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs7_read, 0, 2, _IS_BO
ZEND_ARG_INFO(1, certs)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_verify, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, signerscerts, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cainfo, IS_ARRAY, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extracerts, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, content, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pk7, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sigfile, IS_STRING, 1, "null")
ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, encoding, "OPENSSL_ENCODING_SMIME")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_encrypt, 0, 4, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0)
ZEND_ARG_INFO(0, recipcerts)
ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher, IS_LONG, 0, "OPENSSL_CIPHER_RC2_40")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_sign, 0, 5, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0)
ZEND_ARG_INFO(0, signcert)
ZEND_ARG_INFO(0, signkey)
ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extracertsfilename, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_decrypt, 0, 4, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, infilename, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0)
ZEND_ARG_INFO(0, recipcert)
ZEND_ARG_INFO(0, recipkey)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME")
ZEND_END_ARG_INFO()
#define arginfo_openssl_cms_read arginfo_openssl_pkcs7_read
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_private_encrypt, 0, 3, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
ZEND_ARG_INFO(1, crypted)
@@ -353,6 +396,11 @@ ZEND_FUNCTION(openssl_pkcs7_encrypt);
ZEND_FUNCTION(openssl_pkcs7_sign);
ZEND_FUNCTION(openssl_pkcs7_decrypt);
ZEND_FUNCTION(openssl_pkcs7_read);
ZEND_FUNCTION(openssl_cms_verify);
ZEND_FUNCTION(openssl_cms_encrypt);
ZEND_FUNCTION(openssl_cms_sign);
ZEND_FUNCTION(openssl_cms_decrypt);
ZEND_FUNCTION(openssl_cms_read);
ZEND_FUNCTION(openssl_private_encrypt);
ZEND_FUNCTION(openssl_private_decrypt);
ZEND_FUNCTION(openssl_public_encrypt);
@@ -416,6 +464,11 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(openssl_pkcs7_sign, arginfo_openssl_pkcs7_sign)
ZEND_FE(openssl_pkcs7_decrypt, arginfo_openssl_pkcs7_decrypt)
ZEND_FE(openssl_pkcs7_read, arginfo_openssl_pkcs7_read)
ZEND_FE(openssl_cms_verify, arginfo_openssl_cms_verify)
ZEND_FE(openssl_cms_encrypt, arginfo_openssl_cms_encrypt)
ZEND_FE(openssl_cms_sign, arginfo_openssl_cms_sign)
ZEND_FE(openssl_cms_decrypt, arginfo_openssl_cms_decrypt)
ZEND_FE(openssl_cms_read, arginfo_openssl_cms_read)
ZEND_FE(openssl_private_encrypt, arginfo_openssl_private_encrypt)
ZEND_FE(openssl_private_decrypt, arginfo_openssl_private_decrypt)
ZEND_FE(openssl_public_encrypt, arginfo_openssl_public_encrypt)

View File

@@ -0,0 +1,68 @@
--TEST--
openssl_cms_decrypt() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$encrypted = tempnam(sys_get_temp_dir(), "cms_dec_basic");
if ($encrypted === false)
die("failed to get a temporary filename!");
$outfile = $encrypted . ".out";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$headers = array("test@test", "testing openssl_cms_encrypt()");
$wrong = "wrong";
$empty = "";
openssl_cms_encrypt($infile, $encrypted, $single_cert, $headers);
var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $privkey));
print("\nDecrypted text:\n");
readfile($outfile);
var_dump(openssl_cms_decrypt($encrypted, $outfile, openssl_x509_read($single_cert), $privkey));
var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $wrong));
var_dump(openssl_cms_decrypt($encrypted, $outfile, $wrong, $privkey));
var_dump(openssl_cms_decrypt($encrypted, $outfile, null, $privkey));
var_dump(openssl_cms_decrypt($wrong, $outfile, $single_cert, $privkey));
var_dump(openssl_cms_decrypt($empty, $outfile, $single_cert, $privkey));
var_dump(openssl_cms_decrypt($encrypted, $empty, $single_cert, $privkey));
var_dump(openssl_cms_decrypt($encrypted, $outfile, $empty, $privkey));
var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $empty));
if (file_exists($encrypted)) {
echo "true\n";
unlink($encrypted);
}
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
?>
--EXPECTF--
bool(true)
Decrypted text:
Now is the winter of our discontent.
bool(true)
Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d
bool(false)
Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d
bool(false)
Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d
bool(false)
bool(false)
bool(false)
bool(false)
Warning: openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert in %s on line %d
bool(false)
Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d
bool(false)
true
true

View File

@@ -0,0 +1,44 @@
--TEST--
openssl_cms_decrypt() and invalid parameters
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline) {
var_dump($errstr);
}
set_error_handler("myErrorHandler");
$a = 1;
$b = 1;
$c = new stdclass;
$d = new stdclass;
try {
var_dump(openssl_cms_decrypt($a, $b, $c, $d));
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump($c);
var_dump(openssl_cms_decrypt($b, $b, $b, $b));
var_dump(openssl_cms_decrypt($a, $b, "", ""));
var_dump(openssl_cms_decrypt($a, $b, true, false));
var_dump(openssl_cms_decrypt($a, $b, 0, 0));
echo "Done\n";
?>
--EXPECT--
Object of class stdClass could not be converted to string
object(stdClass)#1 (0) {
}
string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert"
bool(false)
string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert"
bool(false)
string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert"
bool(false)
string(64) "openssl_cms_decrypt(): Unable to coerce parameter 3 to x509 cert"
bool(false)
Done

View File

@@ -0,0 +1,60 @@
--TEST--
openssl_cms_encrypt() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$outfile = tempnam(sys_get_temp_dir(), "cms_enc_basic");
if ($outfile === false)
die("failed to get a temporary filename!");
$outfile2 = $outfile . ".out";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$wrongkey = "file://" . __DIR__ . "/private_rsa_2048.key";
$multi_certs = array($single_cert, $single_cert);
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_encrypt()");
$headers = array("test@test", "testing openssl_cms_encrypt()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $headers));
var_dump(openssl_cms_encrypt($infile, $outfile, openssl_x509_read($single_cert), $headers));
var_dump(openssl_cms_decrypt($outfile, $outfile2, $single_cert, $privkey));
readfile($outfile2);
var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $assoc_headers));
var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $empty_headers));
var_dump(openssl_cms_encrypt($wrong, $outfile, $single_cert, $headers));
var_dump(openssl_cms_encrypt($empty, $outfile, $single_cert, $headers));
var_dump(openssl_cms_encrypt($infile, $empty, $single_cert, $headers));
var_dump(openssl_cms_encrypt($infile, $outfile, $wrong, $headers));
var_dump(openssl_cms_encrypt($infile, $outfile, $empty, $headers));
var_dump(openssl_cms_encrypt($infile, $outfile, $multi_certs, $headers));
var_dump(openssl_cms_encrypt($infile, $outfile, array_map('openssl_x509_read', $multi_certs) , $headers));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($outfile2)) {
echo "true\n";
unlink($outfile2);
}
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
Now is the winter of our discontent.
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)
true
true

View File

@@ -0,0 +1,49 @@
--TEST--
openssl_cms_encrypt() der test
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip";
?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$tname = tempnam(sys_get_temp_dir(), "ssl");
if ($tname === false)
die("failed to get a temporary filename!");
$cryptfile= $tname . ".der";
$decryptfile = $tname . ".out";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$headers = array("test@test", "testing openssl_cms_encrypt()");
var_dump(openssl_cms_encrypt($infile, $cryptfile, $single_cert, $headers, OPENSSL_CMS_BINARY, OPENSSL_ENCODING_DER));
if (openssl_cms_decrypt($cryptfile, $decryptfile, $single_cert, $privkey, OPENSSL_ENCODING_DER) == false) {
print "DER decrypt error\n";
print "recipient:\n";
readfile($single_cert);
print "input:\n";
readfile($infile);
$der=file_get_contents($cryptfile);
print "outfile base64:\n" . base64_encode($der) . "\n--------\n";
while (( $errstr=openssl_error_string()) != false) {
print $errstr . "\n";
}
} else {
readfile($decryptfile);
}
if (file_exists($cryptfile)) {
echo "true\n";
unlink($cryptfile);
}
if (file_exists($decryptfile)) {
echo "true\n";
unlink($decryptfile);
}
unlink($tname);
?>
--EXPECTF--
bool(true)
Now is the winter of our discontent.
true
true

View File

@@ -0,0 +1,48 @@
--TEST--
openssl_cms_encrypt() pem test
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip";
?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$tname = tempnam(sys_get_temp_dir(), "ssl");
if ($tname === false)
die("failed to get a temporary filename!");
$cryptfile= $tname . ".pem";
$decryptfile = $tname . ".pemout";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$headers = array("test@test", "testing openssl_cms_encrypt()");
var_dump(openssl_cms_encrypt($infile, $cryptfile, $single_cert, $headers, OPENSSL_CMS_BINARY, OPENSSL_ENCODING_PEM));
if (openssl_cms_decrypt($cryptfile, $decryptfile, $single_cert, $privkey, OPENSSL_ENCODING_PEM) == false) {
print "PEM decrypt error\n";
print "recipient:\n";
readfile($single_cert);
print "input:\n";
readfile($infile);
print "outfile:\n";
readfile($cryptfile);
while (( $errstr=openssl_error_string()) != false) {
print $errstr . "\n";
}
} else {
readfile($decryptfile);
}
if (file_exists($cryptfile)) {
echo "true\n";
unlink($cryptfile);
}
if (file_exists($decryptfile)) {
echo "true\n";
unlink($decryptfile);
}
unlink($tname);
?>
--EXPECTF--
bool(true)
Now is the winter of our discontent.
true
true

View File

@@ -0,0 +1,44 @@
--TEST--
openssl_cms_read() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = file_get_contents(__DIR__ . "/cert.p7b");
$certfile = file_get_contents(__DIR__ . "/cert.crt");
$result = [];
var_dump(openssl_cms_read("", $result));
var_dump(openssl_cms_read($certfile, $result));
var_dump(openssl_cms_read($infile, $result));
var_dump($result);
?>
--EXPECT--
bool(false)
bool(false)
bool(true)
array(1) {
[0]=>
string(1249) "-----BEGIN CERTIFICATE-----
MIIDbDCCAtWgAwIBAgIJAK7FVsxyN1CiMA0GCSqGSIb3DQEBBQUAMIGBMQswCQYD
VQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcTDFBv
cnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8wHQYJ
KoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0MB4XDTA4MDYzMDEwMjg0M1oXDTA4
MDczMDEwMjg0M1owgYExCzAJBgNVBAYTAkJSMRowGAYDVQQIExFSaW8gR3JhbmRl
IGRvIFN1bDEVMBMGA1UEBxMMUG9ydG8gQWxlZ3JlMR4wHAYDVQQDExVIZW5yaXF1
ZSBkbyBOLiBBbmdlbG8xHzAdBgkqhkiG9w0BCQEWEGhuYW5nZWxvQHBocC5uZXQw
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMteno+QK1ulX4/WDAVBYfoTPRTz
e4SZLwgael4jwWTytj+8c5nNllrFELD6WjJzfjaoIMhCF4w4I2bkWR6/PTqrvnv+
iiiItHfKvJgYqIobUhkiKmWa2wL3mgqvNRIqTrTC4jWZuCkxQ/ksqL9O/F6zk+aR
S1d+KbPaqCR5Rw+lAgMBAAGjgekwgeYwHQYDVR0OBBYEFNt+QHK9XDWF7CkpgRLo
Ymhqtz99MIG2BgNVHSMEga4wgauAFNt+QHK9XDWF7CkpgRLoYmhqtz99oYGHpIGE
MIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTAT
BgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5n
ZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0ggkArsVWzHI3UKIw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCP1GUnStC0TBqngr3Kx+zS
UW8KutKO0ORc5R8aV/x9LlaJrzPyQJgiPpu5hXogLSKRIHxQS3X2+Y0VvIpW72LW
PVKPhYlNtO3oKnfoJGKin0eEhXRZMjfEW/kznY+ZZmNifV2r8s+KhNAqI4PbClvn
4vh8xF/9+eVEj+hM+0OflA==
-----END CERTIFICATE-----
"
}

View File

@@ -0,0 +1,64 @@
--TEST--
openssl_cms_sign() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/cert.crt";
$outfile = tempnam(sys_get_temp_dir(), "ssl");
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_sign()");
$headers = array("test@test", "testing openssl_cms_sign()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers));
$s = stat($outfile);
if ($s['size'] < 500) {
print "size failure, not big enough.";
}
var_dump(openssl_cms_sign($infile, $outfile, $single_cert, $privkey, $headers));
var_dump(openssl_cms_sign($infile, $outfile, $single_cert, $privkey, $assoc_headers));
var_dump(openssl_cms_sign($infile, $outfile, $single_cert, $privkey, $empty_headers));
var_dump(openssl_cms_sign($wrong, $outfile, $single_cert, $privkey, $headers));
var_dump(openssl_cms_sign($empty, $outfile, $single_cert, $privkey, $headers));
var_dump(openssl_cms_sign($infile, $empty, $single_cert, $privkey, $headers));
var_dump(openssl_cms_sign($infile, $outfile, $wrong, $privkey, $headers));
var_dump(openssl_cms_sign($infile, $outfile, $empty, $privkey, $headers));
var_dump(openssl_cms_sign($infile, $outfile, $single_cert, $wrong, $headers));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)
Warning: openssl_cms_sign(): Error opening input file %s in %s on line %d
bool(false)
Warning: openssl_cms_sign(): Error opening input file %s in %s on line %d
bool(false)
Warning: openssl_cms_sign(): Error opening output file %s in %s on line %d
bool(false)
Warning: openssl_cms_sign(): Error getting cert in %s on line %d
bool(false)
Warning: openssl_cms_sign(): Error getting cert in %s on line %d
bool(false)
Warning: openssl_cms_sign(): Error getting private key in %s on line %d
bool(false)
true

View File

@@ -0,0 +1,32 @@
--TEST--
openssl_cms_sign() der tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/cert.crt";
$outfile = tempnam(sys_get_temp_dir(), "ssl");
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_sign()");
$headers = array("test@test", "testing openssl_cms_sign()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $empty_headers, OPENSSL_CMS_DETACHED|OPENSSL_CMS_BINARY, OPENSSL_ENCODING_DER));
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
?>
--EXPECTF--
bool(true)
bool(true)
true

View File

@@ -0,0 +1,47 @@
--TEST--
openssl_cms_sign() and openssl_cms_verify() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$outfile = tempnam(sys_get_temp_dir(), "ssl");
$vout= $outfile . ".vout";
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_sign()");
$headers = array("test@test", "testing openssl_cms_sign()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
print("Plain text:\n");
readfile($infile);
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers));
var_dump(openssl_cms_verify($outfile,OPENSSL_CMS_NOVERIFY, NULL, array(), NULL, $vout));
print("\nValidated content:\n");
readfile($vout);
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
?>
--EXPECTF--
Plain text:
Now is the winter of our discontent.
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true

View File

@@ -0,0 +1,129 @@
--TEST--
openssl_cms_sign() and verify detached tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$outfile = tempnam(sys_get_temp_dir(), "ssl");
$vout= $outfile . ".vout";
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_sign()");
$headers = array("test@test", "testing openssl_cms_sign()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
print("S/MIME attached\nPlain text:\n");
readfile($infile);
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers));
var_dump(openssl_cms_verify($outfile,OPENSSL_CMS_NOVERIFY, NULL, array(), NULL, $vout));
print("\nValidated content:\n");
readfile($vout);
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
// test three forms of detached signatures:
// PEM first
print("\nPEM Detached:\n");
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers,
OPENSSL_CMS_DETACHED|OPENSSL_CMS_BINARY,OPENSSL_ENCODING_PEM));
var_dump(openssl_cms_verify($infile,OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_DETACHED|OPENSSL_CMS_BINARY,
NULL, array(), NULL, $vout, NULL, $outfile, OPENSSL_ENCODING_PEM));
print("\nValidated content:\n");
readfile($vout);
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
// DER next
print("\nDER Detached:\n");
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers,
OPENSSL_CMS_DETACHED|OPENSSL_CMS_BINARY,OPENSSL_ENCODING_DER));
var_dump(openssl_cms_verify($infile,OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_DETACHED|OPENSSL_CMS_BINARY,
NULL, array(), NULL, $vout, NULL, $outfile, OPENSSL_ENCODING_DER));
print("\nValidated content:\n");
readfile($vout);
// extreme measures to avoid stupid temporary errors for failure to unlink a file.
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
$outfile=$outfile . "x";
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
// S/MIME next
print("\nS/MIME Detached (an error):\n");
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers,
OPENSSL_CMS_DETACHED,OPENSSL_ENCODING_SMIME));
var_dump(openssl_cms_verify($infile,OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_DETACHED,
NULL, array(), NULL, $vout, NULL, $outfile, OPENSSL_ENCODING_SMIME));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
?>
--EXPECTF--
S/MIME attached
Plain text:
Now is the winter of our discontent.
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true
PEM Detached:
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true
DER Detached:
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true
S/MIME Detached (an error):
Warning: openssl_cms_sign(): Detached signatures not possible with S/MIME encoding in %s on line %d
bool(false)
Warning: openssl_cms_verify(): Detached signatures not possible with S/MIME encoding in %s on line %d
bool(false)

View File

@@ -0,0 +1,103 @@
--TEST--
openssl_cms_sign() and verify with attached signatures
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$infile = __DIR__ . "/plain.txt";
$outfile = tempnam(sys_get_temp_dir(), "ssl");
$vout= $outfile . ".vout";
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$single_cert = "file://" . __DIR__ . "/cert.crt";
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_sign()");
$headers = array("test@test", "testing openssl_cms_sign()");
$empty_headers = array();
$wrong = "wrong";
$empty = "";
print("S/MIME attached\nPlain text:\n");
readfile($infile);
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers));
var_dump(openssl_cms_verify($outfile,OPENSSL_CMS_NOVERIFY, NULL, array(), NULL, $vout));
print("\nValidated content:\n");
readfile($vout);
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
print("\nPEM Attached:\n");
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers,
OPENSSL_CMS_BINARY,OPENSSL_ENCODING_PEM));
var_dump(openssl_cms_verify($outfile,OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_BINARY,
NULL, array(), NULL, $vout, NULL, NULL, OPENSSL_ENCODING_PEM));
print("\nValidated content:\n");
readfile($vout);
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
// DER next
print("\nDER Attached:\n");
var_dump(openssl_cms_sign($infile, $outfile, openssl_x509_read($single_cert), $privkey, $headers,
OPENSSL_CMS_BINARY,OPENSSL_ENCODING_DER));
var_dump(openssl_cms_verify($outfile,OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_BINARY,
NULL, array(), NULL, $vout, NULL, NULL, OPENSSL_ENCODING_DER));
print("\nValidated content:\n");
readfile($vout);
// extreme measures to avoid stupid temporary errors for failure to unlink a file.
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($vout)) {
echo "true\n";
unlink($vout);
}
?>
--EXPECTF--
S/MIME attached
Plain text:
Now is the winter of our discontent.
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true
PEM Attached:
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true
DER Attached:
bool(true)
bool(true)
Validated content:
Now is the winter of our discontent.
true
true

View File

@@ -0,0 +1,87 @@
--TEST--
openssl_cms_verify() tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$outfile = tempnam(sys_get_temp_dir(), "cms_v_basic");
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$contentfile = $outfile . ".out";
$pkcsfile = __DIR__ . "/openssl_cms_verify__pkcsfile.tmp";
$eml = __DIR__ . "/signed.eml";
$wrong = "wrong";
$empty = "";
$cainfo = array();
var_dump(openssl_cms_verify($wrong, 0));
var_dump(openssl_cms_verify($empty, 0));
var_dump(openssl_cms_verify($eml, 0));
var_dump(openssl_cms_verify($eml, 0, $empty));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile, $pkcsfile));
var_dump(file_get_contents($pkcsfile));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($contentfile)) {
echo "true\n";
unlink($contentfile);
}
?>
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . '/openssl_cms_verify__pkcsfile.tmp');
?>
--EXPECTF--
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)
bool(true)
string(2058) "-----BEGIN CMS-----
MIIFzQYJKoZIhvcNAQcCoIIFvjCCBboCAQExDzANBglghkgBZQMEAgEFADALBgkq
hkiG9w0BBwGgggNwMIIDbDCCAtWgAwIBAgIJAK7FVsxyN1CiMA0GCSqGSIb3DQEB
BQUAMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwx
FTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4g
QW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0MB4XDTA4MDYz
MDEwMjg0M1oXDTA4MDczMDEwMjg0M1owgYExCzAJBgNVBAYTAkJSMRowGAYDVQQI
ExFSaW8gR3JhbmRlIGRvIFN1bDEVMBMGA1UEBxMMUG9ydG8gQWxlZ3JlMR4wHAYD
VQQDExVIZW5yaXF1ZSBkbyBOLiBBbmdlbG8xHzAdBgkqhkiG9w0BCQEWEGhuYW5n
ZWxvQHBocC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMteno+QK1ul
X4/WDAVBYfoTPRTze4SZLwgael4jwWTytj+8c5nNllrFELD6WjJzfjaoIMhCF4w4
I2bkWR6/PTqrvnv+iiiItHfKvJgYqIobUhkiKmWa2wL3mgqvNRIqTrTC4jWZuCkx
Q/ksqL9O/F6zk+aRS1d+KbPaqCR5Rw+lAgMBAAGjgekwgeYwHQYDVR0OBBYEFNt+
QHK9XDWF7CkpgRLoYmhqtz99MIG2BgNVHSMEga4wgauAFNt+QHK9XDWF7CkpgRLo
Ymhqtz99oYGHpIGEMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5k
ZSBkbyBTdWwxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlx
dWUgZG8gTi4gQW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0
ggkArsVWzHI3UKIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCP1GUn
StC0TBqngr3Kx+zSUW8KutKO0ORc5R8aV/x9LlaJrzPyQJgiPpu5hXogLSKRIHxQ
S3X2+Y0VvIpW72LWPVKPhYlNtO3oKnfoJGKin0eEhXRZMjfEW/kznY+ZZmNifV2r
8s+KhNAqI4PbClvn4vh8xF/9+eVEj+hM+0OflDGCAiEwggIdAgEBMIGPMIGBMQsw
CQYDVQQGEwJCUjEaMBgGA1UECBMRUmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcT
DFBvcnRvIEFsZWdyZTEeMBwGA1UEAxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8w
HQYJKoZIhvcNAQkBFhBobmFuZ2Vsb0BwaHAubmV0AgkArsVWzHI3UKIwDQYJYIZI
AWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0B
CQUxDxcNMTcwNTIyMTAxMDU1WjAvBgkqhkiG9w0BCQQxIgQg37MSoxw91phVhwUO
MeurwtXAXK1ADEeYYl/7Bfmz4CsweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQME
ASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG
9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgw
DQYJKoZIhvcNAQEBBQAEgYAw4XcsQ4BIhEuRNspG8RqPE9ODCrTWwXPSQ4B9fzks
KUAsqcefO8AfifY+uuq3/k6Prhl23U5ILth/0fUAIGFLTcIZziaGTwbpgcmRSmNi
jBxatHyKVaGJNGqij5KRk8vhEpy5mwOzmkUzYa0r4teXjyfnKhI/h1vUrO3kKybC
5Q==
-----END CMS-----
"
true
true

View File

@@ -0,0 +1,95 @@
--TEST--
openssl_cms_verify() der tests
--SKIPIF--
<?php if (!extension_loaded("openssl")) print "skip"; ?>
--FILE--
<?php
$outfile = tempnam(sys_get_temp_dir(), "ssl");
if ($outfile === false) {
die("failed to get a temporary filename!");
}
$contentfile = tempnam(sys_get_temp_dir(), "ssl");
if ($contentfile === false) {
die("failed to get a temporary filename!");
}
$pkcsfile = __DIR__ . "/openssl_cms_verify__pkcsfile.tmp";
$eml = __DIR__ . "/signed.eml";
$wrong = "wrong";
$empty = "";
$cainfo = array();
$plain = __DIR__ . "/plain.txt";
$p7file = __DIR__ . "/shakespeare.p7s";
$pemfile = __DIR__ . "/shakespeare.pem";
var_dump(openssl_cms_verify($wrong, 0));
var_dump(openssl_cms_verify($empty, 0));
var_dump(openssl_cms_verify($eml, 0));
var_dump(openssl_cms_verify($eml, 0, $empty));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile));
var_dump(openssl_cms_verify($eml, OPENSSL_CMS_NOVERIFY, $outfile, $cainfo, $outfile, $contentfile, $pkcsfile));
var_dump(openssl_cms_verify($plain, OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_BINARY|OPENSSL_CMS_DETACHED,$outfile,$cainfo,NULL,$contentfile,$pkcsfile,$p7file,OPENSSL_ENCODING_DER));
var_dump(openssl_cms_verify($plain, OPENSSL_CMS_NOVERIFY|OPENSSL_CMS_BINARY|OPENSSL_CMS_DETACHED,$outfile,$cainfo,NULL,$contentfile,$pkcsfile,$pemfile,OPENSSL_ENCODING_PEM));
var_dump(file_get_contents($pkcsfile));
if (file_exists($outfile)) {
echo "true\n";
unlink($outfile);
}
if (file_exists($contentfile)) {
echo "true\n";
unlink($contentfile);
}
?>
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . '/openssl_cms_verify__pkcsfile.tmp');
?>
--EXPECTF--
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
string(2049) "-----BEGIN CMS-----
MIIFyQYJKoZIhvcNAQcCoIIFujCCBbYCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
hvcNAQcBoIIDcDCCA2wwggLVoAMCAQICCQCuxVbMcjdQojANBgkqhkiG9w0BAQUF
ADCBgTELMAkGA1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUgZG8gU3VsMRUw
EwYDVQQHEwxQb3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVlIGRvIE4uIEFu
Z2VsbzEfMB0GCSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldDAeFw0wODA2MzAx
MDI4NDNaFw0wODA3MzAxMDI4NDNaMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMR
UmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UE
AxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vs
b0BwaHAubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLXp6PkCtbpV+P
1gwFQWH6Ez0U83uEmS8IGnpeI8Fk8rY/vHOZzZZaxRCw+loyc342qCDIQheMOCNm
5Fkevz06q757/oooiLR3yryYGKiKG1IZIiplmtsC95oKrzUSKk60wuI1mbgpMUP5
LKi/Tvxes5PmkUtXfimz2qgkeUcPpQIDAQABo4HpMIHmMB0GA1UdDgQWBBTbfkBy
vVw1hewpKYES6GJoarc/fTCBtgYDVR0jBIGuMIGrgBTbfkByvVw1hewpKYES6GJo
arc/faGBh6SBhDCBgTELMAkGA1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUg
ZG8gU3VsMRUwEwYDVQQHEwxQb3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVl
IGRvIE4uIEFuZ2VsbzEfMB0GCSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldIIJ
AK7FVsxyN1CiMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAj9RlJ0rQ
tEwap4K9ysfs0lFvCrrSjtDkXOUfGlf8fS5Wia8z8kCYIj6buYV6IC0ikSB8UEt1
9vmNFbyKVu9i1j1Sj4WJTbTt6Cp36CRiop9HhIV0WTI3xFv5M52PmWZjYn1dq/LP
ioTQKiOD2wpb5+L4fMRf/fnlRI/oTPtDn5QxggIfMIICGwIBATCBjzCBgTELMAkG
A1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUgZG8gU3VsMRUwEwYDVQQHEwxQ
b3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVlIGRvIE4uIEFuZ2VsbzEfMB0G
CSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldAIJAK7FVsxyN1CiMAsGCWCGSAFl
AwQCAaCB5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEP
Fw0yMDAzMTMxMDMxMThaMC8GCSqGSIb3DQEJBDEiBCD7i6er2GffWfJgrK5Yi2Kh
XfedL51/uszuPjxImv7g1jB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjAL
BglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMC
AgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkq
hkiG9w0BAQEFAASBgBphoY0L/jnrzSIOpaS0b2Yzfw9CuuShcUA3oiib/tFn3mzV
gSfYaiIdL0d4FSMRiLFkkbBrxBKD+oMZIMI7ZurpQpqKq0OGPzORflh3sfFLqSI1
8Txoc8qJ5JKpip3W9IQwIwPpAU4HhBgWP2HPODY2/Q3bDtUQ3I9KrJIewr9Q
-----END CMS-----
"
true
true

View File

@@ -0,0 +1 @@
Now is the winter of our discontent.

Binary file not shown.

View File

@@ -0,0 +1,33 @@
-----BEGIN CMS-----
MIIFyQYJKoZIhvcNAQcCoIIFujCCBbYCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
hvcNAQcBoIIDcDCCA2wwggLVoAMCAQICCQCuxVbMcjdQojANBgkqhkiG9w0BAQUF
ADCBgTELMAkGA1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUgZG8gU3VsMRUw
EwYDVQQHEwxQb3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVlIGRvIE4uIEFu
Z2VsbzEfMB0GCSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldDAeFw0wODA2MzAx
MDI4NDNaFw0wODA3MzAxMDI4NDNaMIGBMQswCQYDVQQGEwJCUjEaMBgGA1UECBMR
UmlvIEdyYW5kZSBkbyBTdWwxFTATBgNVBAcTDFBvcnRvIEFsZWdyZTEeMBwGA1UE
AxMVSGVucmlxdWUgZG8gTi4gQW5nZWxvMR8wHQYJKoZIhvcNAQkBFhBobmFuZ2Vs
b0BwaHAubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLXp6PkCtbpV+P
1gwFQWH6Ez0U83uEmS8IGnpeI8Fk8rY/vHOZzZZaxRCw+loyc342qCDIQheMOCNm
5Fkevz06q757/oooiLR3yryYGKiKG1IZIiplmtsC95oKrzUSKk60wuI1mbgpMUP5
LKi/Tvxes5PmkUtXfimz2qgkeUcPpQIDAQABo4HpMIHmMB0GA1UdDgQWBBTbfkBy
vVw1hewpKYES6GJoarc/fTCBtgYDVR0jBIGuMIGrgBTbfkByvVw1hewpKYES6GJo
arc/faGBh6SBhDCBgTELMAkGA1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUg
ZG8gU3VsMRUwEwYDVQQHEwxQb3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVl
IGRvIE4uIEFuZ2VsbzEfMB0GCSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldIIJ
AK7FVsxyN1CiMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAj9RlJ0rQ
tEwap4K9ysfs0lFvCrrSjtDkXOUfGlf8fS5Wia8z8kCYIj6buYV6IC0ikSB8UEt1
9vmNFbyKVu9i1j1Sj4WJTbTt6Cp36CRiop9HhIV0WTI3xFv5M52PmWZjYn1dq/LP
ioTQKiOD2wpb5+L4fMRf/fnlRI/oTPtDn5QxggIfMIICGwIBATCBjzCBgTELMAkG
A1UEBhMCQlIxGjAYBgNVBAgTEVJpbyBHcmFuZGUgZG8gU3VsMRUwEwYDVQQHEwxQ
b3J0byBBbGVncmUxHjAcBgNVBAMTFUhlbnJpcXVlIGRvIE4uIEFuZ2VsbzEfMB0G
CSqGSIb3DQEJARYQaG5hbmdlbG9AcGhwLm5ldAIJAK7FVsxyN1CiMAsGCWCGSAFl
AwQCAaCB5DAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEP
Fw0yMDAzMTMxMDMxMThaMC8GCSqGSIb3DQEJBDEiBCD7i6er2GffWfJgrK5Yi2Kh
XfedL51/uszuPjxImv7g1jB5BgkqhkiG9w0BCQ8xbDBqMAsGCWCGSAFlAwQBKjAL
BglghkgBZQMEARYwCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMC
AgIAgDANBggqhkiG9w0DAgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDANBgkq
hkiG9w0BAQEFAASBgBphoY0L/jnrzSIOpaS0b2Yzfw9CuuShcUA3oiib/tFn3mzV
gSfYaiIdL0d4FSMRiLFkkbBrxBKD+oMZIMI7ZurpQpqKq0OGPzORflh3sfFLqSI1
8Txoc8qJ5JKpip3W9IQwIwPpAU4HhBgWP2HPODY2/Q3bDtUQ3I9KrJIewr9Q
-----END CMS-----