Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sign .mobileconfig on a PHP server

Could anyone please tell me how to use openssl smime -sign -signer cert.pem -inkey key.pem -certfile ca-bundle.pem -nodetach -outform der -in profile-uns.mobileconfig -out profile-sig.mobileconfig this within PHP (this one worked properly!)?

I tried

$path = __DIR__ . DIRECTORY_SEPARATOR;  // my actual directory
$infilename = $path . 'profile.mobileconfig'; // my unsigned profile
$outfilename = $path . 'profile-sig.mobileconfig'; // my signed profile
$signcert = file_get_contents($path . 'cert.pem'); // my certificate to sign
$privkey = file_get_contents($path . 'key.pem'); // my private key of the certificate
$extracerts = $path . 'ca-bundle.pem'; // the cert chain of my CA

echo openssl_pkcs7_sign($infilename, $outfilename , $signcert, $privkey, array(), PKCS7_NOATTR,$extracerts);

without success. I also tried all of the PKCS7 attributes...

like image 935
alve89 Avatar asked Mar 16 '23 08:03

alve89


2 Answers

Calling openssl smime with exec works fine:

exec('openssl smime -sign -signer cert.pem -inkey key.pem -certfile ca-bundle.pem -nodetach -outform der -in profile.mobileconfig -out profile-sig.mobileconfig');
like image 199
alve89 Avatar answered Mar 23 '23 18:03

alve89


Actually, there's an easy approach to solve this problem:

/**
 * Sign MobileConfig
 *
 * @string $file_full_pathname   e.g. /tmp/example.mobileconfig
 * @string $certificate_pathname e.g. /etc/cert.d/apple_distribution.cert.pem
 * @string $private_key_pathname e.g. /etc/cert.d/apple_distribution.key.pem
 * @bool   $remove_file          Optional, default is true, if you want to keep your file then set to false.
 *
 * @return string
 */
function signMobileConfig (
    string $file_full_pathname,
    string $certificate_pathname,
    string $private_key_pathname,
    bool $remove_file = true
) {
    openssl_pkcs7_sign(
        $file_full_pathname,
        $file_full_pathname.'.sig',
        file_get_contents($certificate_pathname),
        file_get_contents($private_key_pathname),
        [], 0
    );

    $signed = file_get_contents($file_full_pathname.'.sig');

    if ($remove_file) {
        unlink($file_full_pathname.'.sig');
        unlink($file_full_pathname);
    }

    $trimmed = preg_replace('/(.+\n)+\n/', '', $signed, 1);
    return base64_decode($trimmed);
}

result of signed config file

Feel free to modify the code above to fulfill your demands.

like image 22
Jason C. Avatar answered Mar 23 '23 17:03

Jason C.