5

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

jww
  • 97,681
  • 90
  • 411
  • 885
alve89
  • 971
  • 1
  • 9
  • 31

2 Answers2

5

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');
sebix
  • 2,943
  • 2
  • 28
  • 43
alve89
  • 971
  • 1
  • 9
  • 31
3

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.

Jason C.
  • 31
  • 1
  • 1
  • 6