OpenSSL SMIME output to stdout PHP exec command - php

I have the following running code on PHP7.
$command = "openssl smime -verify -inform DER -in ".$path." -noverify -out ".PATH_XML_EXTRACT.$filename_output;
exec( $command, $output, $return_var );
The openssl command creates the file properly. Can I avoid to store the message content to the output file? I want to get the message as a string (for example in the $output variable) and managing the flow in memory (no writing on the disk).
Any suggestions?

Related

.P12 Certificate in PHP cURL to an endpoint [duplicate]

i have to connect to a webservice, where a pkcs12 certificate is a must. the idea was to use curl in a bash script (under OS X, to be specific).
i have learnt that one of the few things curl cannot do in communication, is handling pkcs12 certificates (.p12). what are my options?
i have read that converting the certificate to PEM format would work (using openssl), however i have no idea how to tell curl that it gets a PEM and should communicate with a webservice requesting PKCS12 certificates.
converting pkcs12 to pem would be done like this (e.g.), it worked for me, however i haven't successfully used them with curl:
openssl pkcs12 -in mycert.p12 -out file.key.pem -nocerts -nodes
openssl pkcs12 -in mycert.p12 -out file.crt.pem -clcerts -nokeys
any hints? or, any alternatives to curl? the solution should be commandline based.
I think you have already resolved but I had the same problem. I answer to share my solution.
If you have a .p12 file your approach is right.
First of all, you have to get the cert and the key separated from the p12 file.
As an example, if you have a mycert.p12 file execute
openssl pkcs12 -in mycert.p12 -out file.key.pem -nocerts -nodes
openssl pkcs12 -in mycert.p12 -out file.crt.pem -clcerts -nokeys
Then you have to make the call to your url. For instance, assume that you want to get the WSDL of a specific web service
curl -E ./file.crt.pem --key ./file.key.pem https://myservice.com/service?wsdl
If the files file.crt.pem and file.key.pem are in your working folder "./" is mandatory.
Check if you have a newer curl. Newer versions can handle PKCS12 outright.
Tangentially, quote the password, or individually escape all shell metacharacters.
curl --cert-type P12 --cert cert.p12:'password' https://yoursite.com
bioffes answer is correct.
He was suggesting to do:
curl --cert-type P12 --cert cert.p12:password https://yoursite.com
For some reason that didn't work for me. I was getting:
curl could not open PKCS12 file
I just ended up exporting the p12 file without a password and ended up just using the following format.
curl --cert-type P12 --cert cert.p12 https://yoursite.com
You can easily check to see if your curl can handle p12. Very likely it does. Just do man curl and scroll down til you find the cert-type. Mine was like this:
--cert-type <type>
(TLS) Tells curl what type the provided client certificate is using. PEM, DER, ENG and P12 are recognized types. If not specified, PEM is assumed.
If this option is used several times, the last one will be used.
(I don't believe cmmd + F works to text not visible in the terminal. So you have to scroll down.

PHP escapeshellarg messing up my password

$passphrase = "';__!!??()[]";
$passphrase = escapeshellarg($passphrase);
shell_exec("openssl\openssl.exe genrsa -des3 -passout pass:${passphrase} -out test.key 2048");
#Here the password works
echo system("openssl\openssl.exe rsa -in test.key -passin pass:${passphrase} -noout -text");
This code works fine to generate a key with openssl. I can also read the key without any problem. But when I want to read the key from the command line I'm unable to decrypt it. I use exactly the same command as in the code. The only difference is, that I copy the passphrase to the command line as it is written in the code. This always fails with a bad decrypt error.
How can I fix this issue?
Edit: To make this more clear. This does not work when run from terminal:
openssl\openssl.exe rsa -in test.key -passin pass:"';__!!??()[]" -noout -text
Why don't you use PHP's OpenSSL library instead of the shell?
http://php.net/manual/en/ref.openssl.php

Running script through shell_exec not giving the same output is when running on the server

I'm having as issue with running a script using shell_exec in PHP.
When I log onto the server and run the script I get the correct output but when running it through the webpage it doesn't seem to be completing the commands.
The script is to use openssl to create .pem, .pfx and .p12 files from .crt and .key files.
Bash Script is below:
#!/bin/bash
#Script to create all the SSL certs needed from the .key and .crt files
set -o errexit
echo "Starting script....<br><br>"
echo "openssl pkcs12 -export -in $1.crt -inkey $1.key -out $1.p12 -passout pass:$2"
openssl pkcs12 -export -in $1.crt -inkey $1.key -out $1.p12 -passout pass:$2
echo "P12 Complete.<br><br>"
openssl pkcs12 -in $1.p12 -nodes -out $1.pem -passin pass:$2 -passout pass:$2
echo "PEM Complete.<br><br>"
openssl pkcs12 -inkey $1.pem -in $1.crt -export -out $1.pfx -passout pass:$2
echo "PFX complete.<br><br>"
mkdir $1_certs
mv $1.key $1_certs/$1.key
mv $1.crt $1_certs/$1.crt
mv $1.pem $1_certs/$1.pem
mv $1.p12 $1_certs/$1.p12
mv $1.pfx $1_certs/$1.pfx
echo "Password: " $2 >> $1_certs/password.txt
echo "ZIPing files.<br><br>"
zip $1_certs.zip $1_certs
echo "COMPLETE<br><br>"
PHP is below:
<?php
if (isset($_GET['cert_name'])) {
$cert_name = $_GET['cert_name'];
$password = $_GET['password'];
echo "/home/<username>/ssl $cert_name $password <br><br>";
$message=shell_exec("/home/<username>/ssl $cert_name $password");
echo $message;
}
?>
The abundance of echo's in both was to aid in troubleshooting.
The webpage is a basic table with 2 inputs and a submit button.
When I Run this in the webpage it gets to the openssl command to create the .p12 and fails.
If I remove the set -o errexit so that it runs completely through regardless of errors I can see that it doesnt even try to create the directory or move the files, I just see all the echo's. Its as if it just runs the echos and ignores the commands.
I have an echo in before the command to create the p12 file and it shows that it is getting all the correct details.
I'm at a loss of where to go from here. Any help would be appreciated.
From the manual on shell_exec
Return Values
The output from the executed command or NULL if an error occurred or the command produces no output.
Note:
This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution failures using this function. exec() should be used when access to the program exit code is required.
In debugging, echo, and print/print_r variations aren't very helpful, because they type cast null to a string. Instead you could use var_dump, which guarantees output for every input even if it is null.
As far as why it's failing there is a way to get back any information from STDERR by redirecting STDERR to STDOUT.
$message = shell_exec("/home/<username>/ssl $cert_name $password 2>&1");
It's also important to note that you should escape any arguments passed to the shell via escapeshellarg
If I had to guess at why it's failing my best guess would be that whatever user PHP is running under (if you're doing this via your web server, for example, and using Apache httpd with mod_php, it probably doesn't have the necessary permissions to execute /home/<username>/ssl. You should be able to determine that for sure by checking permissions on the file and confirming with STDERR information back from the shell.

Adding intermediate certificate to openssl_pkcs7_sign

I am using this code to sign a file :
openssl_pkcs7_sign($in,$out,
cert.crt,
cert.key,
array(),
PKCS7_NOATTR
);
However it still appears as not verified when it is opened.
On the contrary, this openssl command works fine:
openssl smime -sign -in in -out out -signer cert.crt -inkey cert.key -certfile ca-bundle -outform der -nodetach
Why is the PHP code not working ?
OK,
openssl_pkcs7_sign($in,$out,
cert.crt,
cert.key,
array(),
PKCS7_NOATTR,
"/real/path/of/ca/intermeidate/cert/file.pem"
);
Did the trick. The last $extracerts arg uses real path instead of file://

Linux Openssl command to encrypt file that will be decrypted through PHP

I have to encrypt files that will be decrypted on demand with PHP :
$fh = fopen('encrypted_file', 'rb');
$content = fread($fh, $size);
print mcrypt_decrypt(MCRYPT_TRIPLEDES, 'myPassword', $content, MCRYPT_MODE_ECB);
fclose($fh);
I cannot change the PHP code as it is used many times in the site.
Otherwise, I have to seriously prove that the change is mandatory.
Now, my problem is to find the Linux OpenSSL command to encrypt files that will be decrypted with the given code.
I tried things like :
openssl enc -e -des3 -k myPassword -nosalt -in text_file -out encrypted_file
But I cannot find the decrypted file through PHP.
May you help me to correct the openssl command?
There are so many options (I tried many, I sware) and I don't find how to make them corresponding to the PHP one.
Regards,
Olivier

Categories